装饰器模式(Decorator Design Pattern)

装饰器模式允许向一个现有的对象添加新的功能,同时又不改变它的结构。装饰器模式创建了一个装饰类,用来包装原有的类,装饰器模式又被称为包装器模式(Wrapper)。

装饰器模式有4个角色:

  1. 抽象构件(Component): 被装饰对象的抽象。
  2. 具体构件(Concrete Component):实现抽象构件,是被装饰的对象。
  3. 抽象装饰器(Decorator): 关联抽象构件,可通过具体装饰器装饰具体构件。
  4. 具体装饰器(Concrete Decorator): 实现抽象装饰器的方法,并对具体构件进行装饰,即为具体构件对象添加新的职责。

示例代码

直接看上面的说明可能会比较模糊,游戏中的武器是很好的一个例子,看下代码:

package decorator

import "fmt"

//武器
type Weapon interface {
    Attack() //攻击
}

//皮肤
type Skin interface {
    Protect() //皮肤有不同的保护值
}

//枪
type Gun struct{}

func (g Gun) Attack() {
    fmt.Println("手枪-射击")
}

//大炮
type Cannon struct{}

func (c Cannon) Attack() {
    fmt.Println("加农大炮——开火")
}

//电玩小子皮肤
type GameBoySkin struct{}

func (g GameBoySkin) Protect() {
    fmt.Println("穿上电玩小子批发武力值+10,保护+10")
}

//游戏角色
type Characters interface {
    Weapon(Weapon)
    Skin(Skin)
    Attack()
}

//游戏角色-鲁班七号
type Luban struct {
    skin   Skin
    weapon Weapon
}

func (l *Luban) Weapon(w Weapon) {
    l.weapon = w
}

func (l *Luban) Skin(s Skin) {
    l.skin = s
    l.skin.Protect()
}
func (l Luban) Attack() {
    l.weapon.Attack()
}

调用:

//武器
var gun Weapon = &Gun{}
var cannon Weapon = &Cannon{}

//皮肤
var gameBoySkin Skin = &GameBoySkin{}

//游戏角色
var luban Characters = &Luban{}
luban.Weapon(gun)
luban.Attack()

luban.Skin(gameBoySkin) //穿上皮肤
luban.Weapon(cannon)    //使用加农大炮
luban.Attack()          //攻击

// Output:
// 手枪-射击
// 穿上电玩小子批发武力值+10,保护+10
// 加农大炮——开火

装饰器模式和桥接模式区别

适配器模式是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的;

而装饰器模式不是要改变被装饰者对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方法而提升性能。比如上面例子中游戏角色通过改变武器达到不同的武力值,通过增加皮肤也可以增加武力和保护值。

results matching ""

    No results matching ""