golang设计模式之组合模式

作者: adm 分类: go 发布时间: 2022-08-04

组合模式
定义
组合模式(Composite),将对象组合成树形结构以表示’部分-整体’的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性。

组合模式,将一组对象组织成树形结构,将单个对象和组合对象都看做树中的节点,以统一处理逻辑,并且它利用树形结构的特点,递归地处理每个子树,依次简化代码实现。使用组合模式的前提在于,你的业务场景必须能够表示成树形结构。所以,组合模式的应用场景也比较局限,它并不是一种很常用的设计模式。

适用范围
1、您想表示对象的部分-整体层次结构(树形结构);

2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

优点
1、高层模块调用简单;

2、节点自由增加。

缺点
1、设计较复杂,客户端需要花更多时间理清类之间的层次关系;

2、不容易限制容器中的构件;

3、不容易用继承的方法来增加构件的新功能;

代码实现
公司有部门,部门下面有员工,使用组合模式来表示这种层次关系。

type Employee struct {
	no           int
	name         string
	dept         string
	salary       int
	subordinates []*Employee
}

func NewEmployee(no int, name, dept string, salary int) *Employee {
	return &Employee{
		no:           no,
		name:         name,
		dept:         dept,
		salary:       salary,
		subordinates: []*Employee{},
	}
}

func (e *Employee) add(em *Employee) {
	e.subordinates = append(e.subordinates, em)
}

func (e *Employee) remove(em *Employee) {
	for index, item := range e.subordinates {
		if item.no == em.no {
			e.subordinates = e.subordinates[:index+copy(e.subordinates[index:], e.subordinates[index+1:])]
			break
		}
	}
}

func (e *Employee) getSubordinates() []*Employee {
	return e.subordinates
}

func (e *Employee) toString() {
	fmt.Println(fmt.Sprintf("Employee:no:%d;name:%s;dept:%s;salary:%d。", e.no, e.name, e.dept, e.salary))
}

测试文件

func TestComposite(t *testing.T) {
	ceo := NewEmployee(1, "马云", "CEO", 1000000)

	headMarketing := NewEmployee(2, "小白", "市场总监", 50000)
	clerk1 := NewEmployee(1001, "小明", "Marketing", 10000)
	clerk2 := NewEmployee(1002, "小张", "Marketing", 10000)

	cto := NewEmployee(3, "小龙", "CTO", 90000)
	tc1 := NewEmployee(1003, "马龙", "Technology", 10000)
	tc2 := NewEmployee(1004, "张龙", "Technology", 10000)

	ceo.add(headMarketing)
	headMarketing.add(clerk1)
	headMarketing.add(clerk2)

	ceo.add(cto)
	cto.add(tc1)
	cto.add(tc2)

	ceo.toString()
	for _, subordinate := range ceo.subordinates {
		fmt.Println("部门", "+++++++++++++++")
		subordinate.toString()
		for _, employee := range subordinate.subordinates {
			employee.toString()
		}
	}
}

结构图

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!