装饰模式使用对象组合的方式动态改变或增加对象行为。Go语言借助于匿名组合和非入侵式接口可以很方便实现装饰模式。使用匿名组合,在装饰器中不必显式定义转调原对象方法。
装饰器模式主要解决继承关系过于复杂的问题,通过组合来代替继承,给原始类添加增强功能,这也是判断装饰器的一个重要依据,除此之外,装饰器还有一个特点,可以对原始类嵌套使用多个装饰器,为了满足这样的需求,在设计的时候,装饰器类需要跟原始继承同步的抽象类或者接口。
Java IO 通过4个基类,扩展出很多子类, 具体如下:
装饰器模式相对于简单的组合关系,有如下特殊点:
package decorator
type Component interface {
Calc() int
}
type ConcreteComponent struct{}
func (*ConcreteComponent) Calc() int {
return 0
}
type MulDecorator struct {
Component
num int
}
func WarpMulDecorator(c Component, num int) Component {
return &MulDecorator{
Component: c,
num: num,
}
}
func (d *MulDecorator) Calc() int {
return d.Component.Calc() * d.num
}
type AddDecorator struct {
Component
num int
}
func WarpAddDecorator(c Component, num int) Component {
return &AddDecorator{
Component: c,
num: num,
}
}
func (d *AddDecorator) Calc() int {
return d.Component.Calc() + d.num
}
测试用例
package decorator
import (
"fmt"
"testing"
)
func TestExampleDecorator(t *testing.T) {
var c Component = &ConcreteComponent{}
c = WarpAddDecorator(c, 10)
c = WarpMulDecorator(c, 8)
res := c.Calc()
fmt.Printf("res %d\n", res)
// Output:
// res 80
}
运行结果
=== RUN TestExampleDecorator
res 80
--- PASS: TestExampleDecorator (0.00s)
PASS