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

什么是装饰者模式

装饰者模式有以下特点:

  • 理论上它们是可以无限包装的(无限套娃)

  • 装饰者和被装饰者们有相同的超类型(super)

  • 想要拓展功能无需修改原有的代码, 定义一个装饰者就可以

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

  • 从”包装”我们可以看到”多用组合,少用继承”

  • 从”拓展”我们可以看到”开闭原则”

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

描述环节

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

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

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


type Heros interface {

    Description()   string

    DEF()   float32

}

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


type mage struct {

    name    string

    def     float32

}


func (m mage) Description() string {

    return m.name

}


func (m mage) DEF() float32 {

    return m.def

}

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


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的类型,那么使用一下看看。


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())

{% asset_img 1.png %}

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

Tags: