装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持原类方法签名完整性的前提下,提供了额外的功能。
装饰器模式的主要组成
- Component(组件):定义了对象的接口,可以给这些对象动态地添加职责。
- Concrete Component(具体组件):定义了对象的一个具体实现。
- Decorator(装饰器):持有一个组件对象的引用,并实现与组件相同的接口。
- Concrete Decorator(具体装饰器):负责给组件添加新的功能。
装饰器模式的实现步骤
- 定义组件接口:这个接口规定了可以装饰的对象的类型。
- 创建具体组件:实现组件接口,定义一个具体的对象。
- 创建装饰器抽象类:实现组件接口,并持有一个组件对象的引用。
- 创建具体装饰器:继承装饰器抽象类,实现具体装饰逻辑。
装饰器模式的优点
- 扩展性:可以在不修改原有对象代码的前提下,通过添加新的装饰器来扩展功能。
- 灵活性:可以在运行时动态地添加或去除职责。
- 低耦合性:装饰器和具体组件之间是松耦合的,增加新的装饰器不需要修改组件代码。
装饰器模式的缺点
- 过度使用:如果过度使用装饰器模式,可能会导致系统变得复杂,难以理解。
- 性能问题:装饰器可能会增加一些性能开销,因为每次装饰都涉及到额外的对象创建和方法调用。
装饰器模式的使用场景
- 当需要在不修改对象源代码的情况下,给对象添加新的功能时。
- 当需要动态地给一个对象添加功能时,这些功能可以是临时的。
package mainimport "fmt"// Component 定义了对象的接口,可以给这些对象动态地添加职责
type Component interface {Operation() string
}// ConcreteComponent 定义了对象的一个具体实现
type ConcreteComponent struct{}func (c *ConcreteComponent) Operation() string {return "ConcreteComponent"
}// Decorator 持有一个Component对象的引用,并实现与Component相同的接口
type Decorator struct {Component Component
}func (d *Decorator) Operation() string {return d.Component.Operation()
}// ConcreteDecorator 负责给Component添加新的功能
type ConcreteDecoratorA struct {Decorator
}func (cda *ConcreteDecoratorA) Operation() string {return cda.Decorator.Operation() + " ConcreteDecoratorA"
}// ConcreteDecoratorB 另一个装饰器,添加不同的功能
type ConcreteDecoratorB struct {Decorator
}func (cdb *ConcreteDecoratorB) Operation() string {return cdb.Decorator.Operation() + " ConcreteDecoratorB"
}func main() {// 创建具体组件component := &ConcreteComponent{}// 动态添加装饰器decoratorA := &ConcreteDecoratorA{Decorator{Component: component}}decoratorB := &ConcreteDecoratorB{Decorator: Decorator{Component: decoratorA}}// 输出装饰后的结果fmt.Println(component.Operation()) // 输出 ConcreteComponentfmt.Println(decoratorA.Operation()) // 输出 ConcreteComponent ConcreteDecoratorAfmt.Println(decoratorB.Operation()) // 输出 ConcreteComponent ConcreteDecoratorA ConcreteDecoratorB
}
装饰器模式主要用于解决继承关系过于复杂的问题,通过组合来替代继承,主要作用是给原始类添加增加功能。
实现方式是继承或接口,如果装饰类的方法大部分和原类相同,用继承。
和代理模式的区别:代码形式上几乎没有区别。代码模式主要是给原始类添加无关的功能,装饰器模式主要是给原始类增强功能,添加的功能都是有关联的。
Go设计模式08-装饰器模式
第17篇-装饰器模式