golang设计模式--装饰器模式

101 阅读2分钟

前提:

创建型模式 : 就是专门用来拿到实例化对象的
装饰器模式是一种结构型模式,强调的是结构,不同于创建型模式

先了解代理模式的代码风格,因为装饰器模式是在此基础上改进的
下面附上代理模式的代码:

type task interface {
   doHomeWork()
}
type zhangSan struct{}

func (z *zhangSan) doHomeWork() {
   fmt.Println("张三的作业")
}

type liSi struct{}

func (l *liSi) doHomeWork() {
   fmt.Println("李四的作业")
}

type wangWu struct{}

func (w *wangWu) doHomeWork() {
   fmt.Println("王五的作业")
}

type writer struct {
   t task //这里就体现了代理模式的思想,就相当于在说,写手有了写作业的功能
   //task本身就是引用类型了,所以不写成 t *task
}

func (w *writer) doHomeWork() {
   fmt.Println("写手开始代写作业")
   w.t.doHomeWork()
   w.answerQuestion()
}

// 甚至于写手还会提供答疑
func (w *writer) answerQuestion() {
   fmt.Println("写手开始答疑")
   w.t.doHomeWork()
}

func newClient(t task) task {
   return &writer{t}
}

func main() {
   z := &zhangSan{}
   c := newClient(z)
   c.doHomeWork()

}

可以发现,写手组合了 task 接口以后,就让写手实现接口,并且绑定新的函数
装饰器模式是把 task 接口不直接组合进写手结构体,而是组合进一个中转的decorator结构体
再使用新的结构体去继承decorator,让新的结构体实现接口,并且绑定新的函数
为了更加灵活使用装饰器模式,下面用一个新的例子:

package main

import "fmt"

type art interface {
   //可以改变卡片的行为就可以叫做艺术
   changeCard()
}

// 颜料
type pigment struct{}

func (p *pigment) changeCard() {
   fmt.Println("颜料可以改变卡片颜色")
}

// 雕刻
type engrave struct{}

func (e *engrave) changeCard() {
   fmt.Println("雕刻可以美化卡片的外层")
}

// 如果是代理模式,那么这里就已经是代理结构体了
// 而装饰器模式就是在代理模式的基础上,把【代理结构体】写成【装饰结构体】
// 然后按照需求去继承装饰结构体
// 装饰器模式相较于代理模式更加的灵活,可以任意顺序的叠加功能
type decorator struct {
   a art
}

// 折纸可以在颜料,雕刻的基础上进一步塑形,所以继承了艺术
type fold struct {
   decorator
}

func (f *fold) changeCard() {
   f.a.changeCard()
   fmt.Println("折纸")
}
func NewFold(a art) art {
   return &fold{decorator{a}}
}

// 剪纸可以在颜料,雕刻的基础上进一步留主去繁,所以继承了艺术
type cut struct {
   decorator
}

func (c *cut) changeCard() {
   c.a.changeCard()
   fmt.Println("剪纸")
}
func NewCut(a art) art {
   return &cut{decorator{a}}
}
func main() {
   f := NewFold(&pigment{})
   f.changeCard()//上颜料,再折纸

   c := NewCut(&engrave{})
   c.changeCard()//先雕刻,再剪纸

   v := NewCut(f)
   v.changeCard()//上颜料,再折纸,最后剪纸
}