概念
装饰模式:动态的给一个对象添加一些额外的职责, 就增加功能来说, 装饰模式比生成子类更为灵活。
Go语言借助于匿名组合和非入侵式接口可以很方便实现装饰模式。
使用匿名组合,在装饰器中不必显式定义转调原对象方法。
具体实现
- 定义一个接口类
- 定义一个具体结构体, 实现上面的接口类
- 定义一个装饰器结构体, 装饰器嵌入接口, 并且实现接口类方法,在接口类方法调用接口类的具体实现的方法。
2中具体结构体是被装饰函数, 3中装饰器结构体实现的函数是装饰函数, 装饰函数调用被装饰函数, 可以自由调用装饰器自身数据, 完成装饰。 被装饰者和装饰器通过接口关联。 形成解耦, 方便动态扩展。
模式的场景和优缺点
使用场景
在不想增加很多接口的情况下扩展函数或者接口。
优点
装饰函数和被装饰函数可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现函数的功能。
缺点
多层装饰比较复杂
代码实现
package main
import "fmt"
// ***************定义一个接口********************
//Shape 模型接口
type Shape interface {
Draw()
}
// ***************end********************
// ***************具体接口实现********************
//Circle 圆形类
type Circle struct{}
//NewCircle 实例化圆形
func NewCircle() *Circle {
return &Circle{}
}
//Draw 输出方法,实现Shape接口
func (c *Circle) Draw() {
fmt.Println("Circle Draw method.")
}
// ***************end********************
// ***************具体装饰器A********************
//RedShapeDecorator 红色装饰器
type RedShapeDecorator struct {
DecoratedShape Shape
}
//NewRedShapeDecorator 实例化红色装饰器
func NewRedShapeDecorator(decShape Shape) *RedShapeDecorator {
return &RedShapeDecorator{
DecoratedShape: decShape,
}
}
//SetRedBorder 装饰器方法
func (rs *RedShapeDecorator) SetRedBorder() {
fmt.Println("Border Color: red")
}
//Draw 实现Shape接口的方法
func (rs *RedShapeDecorator) Draw() {
rs.DecoratedShape.Draw()
rs.SetRedBorder()
}
// ***************end********************
// main函数中使用装饰器
func main() {
circle := NewCircle()
decoratorA := NewRedShapeDecorator(circle)
decoratorA.Draw()
}