设计模式 - 过滤器模式
设计模式 - 装饰器模式

设计模式 - 组合模式

violet posted @ 5 年前 in 笔记 with tags Design Pattern Golang , 212 阅读

意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作数、操作符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。

优点: 1、高层模块调用简单。 2、节点自由增加。

缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

注意事项:定义时为具体类。

 

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
package main
 
import "fmt"
 
type Employee struct {
    Name         string
    Dept         string
    Salary       int
    Subordinates []*Employee
}
 
func NewEmployee(name, dept string, salary int) *Employee {
    return &Employee{
        Name:         name,
        Dept:         dept,
        Salary:       salary,
        Subordinates: []*Employee{},
    }
}
 
func (e *Employee) Add(employee *Employee) {
    e.Subordinates = append(e.Subordinates, employee)
}
 
func (e *Employee) Remove(employee *Employee) {
    for i, item := range e.Subordinates {
        if item.Name == employee.Name {
            e.Subordinates[i] = e.Subordinates[len(e.Subordinates)-1]
            e.Subordinates = e.Subordinates[:len(e.Subordinates)-1]
            return
        }
    }
}
 
func (e *Employee) GetSubordinates() []*Employee {
    return e.Subordinates
}
 
func (e *Employee) ToString() string {
    return fmt.Sprintf("Employee: Name: %s, Dept: %s, Salary: %d", e.Name, e.Dept, e.Salary)
}
 
func main() {
    ceo := NewEmployee("John", "CEO", 23333)
    headSales := NewEmployee("Robert", "HeadSales", 2333)
    headMarket := NewEmployee("Mike", "HeadMarket", 2333)
    clerk1 := NewEmployee("Laura", "marketing", 233)
    clerk2 := NewEmployee("Bob", "marketing", 233)
    sales1 := NewEmployee("Richard", "sales", 233)
    sales2 := NewEmployee("Rob", "sales", 233)
 
    ceo.Add(headSales)
    ceo.Add(headMarket)
 
    headMarket.Add(clerk1)
    headMarket.Add(clerk2)
 
    headSales.Add(sales1)
    headSales.Add(sales2)
 
    queue := []*Employee{ceo}
    for len(queue) != 0 {
        size := len(queue)
        for i := 0; i < size; i++ {
            employee := queue[i]
            fmt.Println(employee.ToString())
            queue = append(queue, employee.Subordinates...)
        }
 
        queue = queue[size:]
    }
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter