-
Notifications
You must be signed in to change notification settings - Fork 184
/
Copy pathcomposite.go
103 lines (95 loc) · 2.35 KB
/
composite.go
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
package composite
import "fmt"
/*
设计思想:
struct不依赖interface
1. 包含角色:
1). 共同的接口MenuComponent,为root和leaf结构体共有的方法
2). root结构体(包含leaf列表)和leaf结构体
3). 将结构体中共同部分的数据抽离,使用匿名组合的方式实现2中的两类结构体
*/
//Menu示例如何使用组合设计模式:Menu和MenuItem
//抽离共同属性部分
type MenuDesc struct {
name string
description string
}
func (desc *MenuDesc) Name() string {
return desc.name
}
func (desc *MenuDesc) Description() string {
return desc.description
}
//MenuItem组合,继承了MenuDesc的方法
type MenuItem struct {
MenuDesc
price float32
}
func NewMenuItem(name, description string, price float32) *MenuItem {
return &MenuItem{
MenuDesc: MenuDesc{
name: name,
description: description,
},
price: price,
}
}
//实现MenuItem Price方法和Print()
func (item *MenuItem) Price() float32 {
return item.price
}
func (item *MenuItem) Print() {
fmt.Printf(" %s, %0.2f\n", item.name, item.price)
fmt.Printf(" -- %s\n", item.description)
}
//接下来实现Menu struct, Menu包含共同部分MenuDesc以及列表, 将列表部分分离出来
/*
MenuGroup, 这里引入接口MenuComponent, 因为child类型是不确定的
此外,由于接口为Menu和MenuItem的共同接口,所以包含Price和Print方法
*/
type MenuComponent interface {
Price() float32
Print()
}
type MenuGroup struct {
child []MenuComponent
}
//MenuGroup需要实现Add、Remove、Find方法
func (group *MenuGroup) Add(component MenuComponent) {
group.child = append(group.child, component)
}
func (group *MenuGroup) Remove(id int) {
group.child = append(group.child[:id], group.child[id+1:]...)
}
func (group *MenuGroup) Find(id int) MenuComponent {
return group.child[id]
}
//Menu结构体
type Menu struct {
MenuDesc
MenuGroup
}
//简单工厂
func NewMenu(name, description string) *Menu {
return &Menu{
MenuDesc: MenuDesc{
name: name,
description: description,
},
}
}
//实现Price和Print方法
func (m *Menu) Price() (price float32) {
for _, v := range m.child {
price += v.Price()
}
return price
}
func (m *Menu) Print() {
fmt.Printf("%s, %s, ¥%.2f\n", m.name, m.description, m.Price())
fmt.Println("------------------------")
for _, v := range m.child {
v.Print()
}
fmt.Println("结束")
}