设计模式:装饰器模式

装饰器模式主要解决要动态的给一个类添加一些新功能,而又不想让这个类变得庞大。
这种模式需要创建一个装饰类来包装扩展原有的类,并且在保证原有的类保持结构一致的前提下,提供额外的功能。

下面是给一个人装饰衣服的实例:

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package decorator
import "fmt"
type Person interface {
Show()
}
// 具体实现
type ConcreteComponent struct {
}
func (c *ConcreteComponent) Show() {
fmt.Print("A Person wears sunglasses; ")
}
// 男人
type Man struct{}
func (m *Man) Show() {
fmt.Print("A man wear a hat!")
}
// 女人
type Woman struct{}
func (w *Woman) Show() {
fmt.Print("A woman wear a skirt!")
}
// TShirt
type TShirtDecorator struct {
Person
Color string
}
func (t *TShirtDecorator) Show() {
t.Person.Show() // 调用父类的 Show() 方法
// "装饰": 增加自己特有的属性
fmt.Print(fmt.Sprintf("Color: %s, TShirt; ", t.Color))
}
func WearTShirt(p Person, c string) Person {
return &TShirtDecorator{
Person: p,
Color: c,
}
}
// Pants
type PantsDecorator struct {
Person
Length int64
}
func (p *PantsDecorator) Show() {
p.Person.Show()
fmt.Print(fmt.Sprintf("Lenght: %dcm, Pants.; ", p.Length))
}
func WearPants(p Person, l int64) Person {
return &PantsDecorator{
Person: p,
Length: l,
}
}
// Shoes
type ShoesDecorator struct {
Person
Size int64
}
func (s *ShoesDecorator) Show() {
s.Person.Show()
fmt.Print(fmt.Sprintf("Size: %d, Shoes; ", s.Size))
}
func WearShoes(p Person, s int64) Person {
return &ShoesDecorator{
Person: p,
Size: s,
}
}
// Examples
func ExampleConcrete_Wear() {
var p Person = &ConcreteComponent{}
p = WearTShirt(p, "Blue")
p = WearPants(p, 100)
p = WearShoes(p, 42)
p.Show()
// Output: A Person wears sunglasses; Color: Blue, TShirt; Lenght: 100cm, Pants.; Size: 42, Shoes;
}
func ExampleMan_Show() {
var xiaoming Person = &Man{}
xiaoming = WearShoes(xiaoming, 43)
xiaoming = WearTShirt(xiaoming, "White")
xiaoming.Show()
// Output:A man wear a hat!Size: 43, Shoes; Color: White, TShirt;
}
func ExampleWoman_Show() {
var xiaohong Person = &Woman{}
xiaohong = WearTShirt(xiaohong, "Red")
xiaohong = WearShoes(xiaohong, 38)
xiaohong.Show()
// Output: A woman wear a skirt!Color: Red, TShirt; Size: 38, Shoes;
}

源码以及测试源码下载地址:https://github.com/h1z3y3/big-talk-go-design-patterns/tree/master/02_decorator

坚持原创技术分享,您的支持将鼓励我继续创作!