和代理模式很相似。不过比代理模式更灵活,动态给类添加功能。符合开闭原则。

案例

一开始有个手机(裸机Phone类),如果需要不断的为这个Phone增添某个功能从而变成一个新功能的Phone,就需要一个装饰器的类,来动态的给一个类额外添加一个指定的功能,而生成另一个类,但原先的类又没有改变,不影响原有系统的稳定。

在装饰器模式中,“裸机”、“有贴膜的手机”、“有手机壳的手机”、“有手机壳&贴膜的手机”都是一个构件。“贴膜装饰器”、“手机壳装饰器”是装饰器也是一个构件。

类图

img

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package main

import "fmt"

type Phone interface {
Show()
}

// 抽象的装饰器,该类本应该是interface,
// 由于Golang语法的interface不可以有成员属性,所以定义为struct来重写show方法
type Decorator struct {
phone Phone
}

func (a *Decorator) Show() {}

// 实现层
type Huawei struct{}

func (a *Huawei) Show() {
fmt.Println("华为手机")
}

type Mi struct{}

func (a *Mi) Show() {
fmt.Println("小米手机")
}

// 具体的装饰器
type MoDecorator struct {
Decorator
}

func (md *MoDecorator) Show() {
md.phone.Show()
fmt.Println("贴膜")
}

func NewMoDecorator(phone Phone) Phone {
return &MoDecorator{Decorator{phone}}
}

// 手机壳
type KDecorator struct {
Decorator
}

func (md *KDecorator) Show() {
md.phone.Show()
fmt.Println("手机壳")
}

func NewKDecorator(phone Phone) Phone {
return &KDecorator{Decorator{phone}}
}
func main() {
hw := &Huawei{}
// hw.Show()
//
md := NewMoDecorator(hw)
hkd := NewKDecorator(hw)
md.Show()
hkd.Show()
kd := NewKDecorator(&Mi{})
kd.Show()
}