设计模式:装饰者模式(Go)

什么是装饰者模式

装饰者模式有以下特点:

  • 理论上它们是可以无限包装的(无限套娃)
  • 装饰者和被装饰者们有相同的超类型(super)
  • 想要拓展功能无需修改原有的代码, 定义一个装饰者就可以

装饰者模式使用了下面的设计原则:

  • 从”包装”我们可以看到”多用组合,少用继承”
  • 从”拓展”我们可以看到”开闭原则”

在不必改变原类文件和使用继承的情况下, 动态地扩展一个对象的功能. 它是通过创建一个包装对象, 也就是装饰来包裹真实的对象

描述环节

上面bb完特点和原则之后,我们开始使用这个模式来解决实际问题。

我们以游戏中角色叠buff为例,如果我们需要很多重buff,怎么用代码描述?

首先定义一个超类型,在Go中用接口实现,用来规范描述角色的几个方法。

1
2
3
4
type Heros interface {
Description() string
DEF() float32
}

然后这两个方法一个是描述叠上什么buff,一个是叠上buff后的防御力。

1
2
3
4
5
6
7
8
9
10
11
12
type mage struct {
name string
def float32
}

func (m mage) Description() string {
return m.name
}

func (m mage) DEF() float32 {
return m.def
}

首先我们上面定义了一个法师类型,下面我们再写个buff的类型

1
2
3
4
5
6
7
8
9
10
11
12
13
type buff struct {
heros Heros
name string
def float32
}

func (b buff) Description() string {
return b.heros.Description()+"+"+b.name
}

func (b buff) DEF() float32 {
return b.heros.DEF() + b.def
}

好了我们写完了加防御力buff的类型,那么使用一下看看。

1
2
3
4
5
6
7
8
hero := mage{name: "战斗法师", def: 10}
buff1 := buff{heros: hero, name: "魔法结界·神圣", def: 12.2}
buff2 := buff{heros: buff1, name: "生命精髓", def: 3.5}
buff3 := buff{heros: buff2, name: "高阶全属性强化", def: 8}
buff4 := buff{heros: buff3, name: "虚假情报·生命", def: 0}
buff5 := buff{heros: buff4, name: "高阶抵抗力强化", def: 15.7}
fmt.Println(buff5.Description())
fmt.Println(buff5.DEF())

可以看出套了几层buff后防御力也涨了好多啊。当然如果想在这个基础上加上可以提供攻击力加成的buff的话,只需要再写一个拥有攻击力加成的结构体,然后实现上面的接口,就可以再套娃下去,这样就一个接口,只需要不断地写出装设者的结构体和方法,就能实现非常多的功能。