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

设计模式 - 组合模式

violet posted @ Jul 08, 2020 06:55:20 AM in 笔记 with tags Design Pattern Golang , 181 阅读

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

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

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

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

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

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

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

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

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

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

 

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