设计模式-组合模式
组合模式(Composite Pattern):将对象组合成树形结构表示来“部分-整体”的层次结构,使用户对单个对象和组合对象的使用具有一致性。
看上去有点抽象,其实就是一种树形结构。比如二叉树,每个非叶子节点都有2个子节点,叶子节点除了没有子节点外和父节点、根节点都是一样的。在通俗来说,比如公司的层级架构,从老板(根节点)到经理(非叶子节点)再到员工(叶子节点),他们有很多共性的东西,比如都有姓名、工号,老板和经理有添加、移除手下员工的能力,而作为员工则只能干活。
从代码实现来说,就是老板、经理、员工使用一个抽象类,而老板和经理实现某些特定的方法,这就是组合模式,十分容易理解。
package main
import (
"fmt"
)
type duty interface {
addStaff(d duty)
getStaff() []duty
printUserInfo()
printEmployeesInfo()
}
type Staff struct {
number string
name string
position string
}
func (s *Staff) printUserInfo() {
fmt.Printf("ID:%s,Name:%s,position:%s\n", s.number, s.name, s.position)
}
func (s *Staff) printEmployeesInfo() {
return
}
func (s *Staff) addStaff(d duty) {
return
}
func (s *Staff) getStaff() []duty {
return []duty{}
}
type Manager struct {
self Staff
arr []duty
}
func (m *Manager) getStaff() []duty {
return m.arr
}
func (m *Manager) addStaff(d duty) {
m.arr = append(m.arr, d)
}
func (m *Manager) printUserInfo() {
m.self.printUserInfo()
}
func (m *Manager) printEmployeesInfo() {
for _, e := range m.arr {
e.printUserInfo()
for _, ee := range e.getStaff() {
ee.printUserInfo()
ee.printEmployeesInfo()
}
}
}
type Employees struct {
self Staff
}
func (e *Employees) addStaff(d duty) {
return
}
func (e *Employees) getStaff() []duty {
return []duty{}
}
func (e *Employees) printUserInfo() {
e.self.printUserInfo()
}
func (e *Employees) printEmployeesInfo() {
return
}
func main() {
ceo := Manager{self: Staff{name: "ceo", number: "001", position: "CEO"}}
techM := Manager{self: Staff{name: "技术经理", number: "002", position: "技术经理"}}
techMG1 := Manager{self: Staff{name: "技术组长1", number: "004", position: "技术组长"}}
techMG2 := Manager{self: Staff{name: "技术组长2", number: "005", position: "技术组长"}}
finaM := Manager{self: Staff{name: "财务经理", number: "003", position: "财务经理"}}
emp1 := Employees{self: Staff{name: "开发1", number: "0041", position: "开发人员"}}
emp2 := Employees{self: Staff{name: "开发2", number: "0052", position: "开发人员"}}
emp3 := Employees{self: Staff{name: "财务1", number: "0031", position: "财务人员"}}
ceo.addStaff(&techM)
ceo.addStaff(&finaM)
techM.addStaff(&techMG1)
techM.addStaff(&techMG2)
techMG1.addStaff(&emp1)
techMG2.addStaff(&emp2)
finaM.addStaff(&emp3)
ceo.printUserInfo()
ceo.printEmployeesInfo()
}
程序输出如下:
ID:001,Name:ceo,position:CEO
ID:002,Name:技术经理,position:技术经理
ID:004,Name:技术组长1,position:技术组长
ID:0041,Name:开发1,position:开发人员
ID:005,Name:技术组长2,position:技术组长
ID:0052,Name:开发2,position:开发人员
ID:003,Name:财务经理,position:财务经理
ID:0031,Name:财务1,position:财务人员
如果不使用组合模式,代码则需要建立一个Manager
类,里面有添加、展示员工方法,再建立一个Employees
类表示员工,这个类仅有printUserInfo
方法。而使用组合模式,则将这2者统一为Staff
类的子类实现相关接口即可,这也是面向抽象编程的思想。
应用场景
- 表示对象的“部分-整体”层次结构时。
- 希望用户忽略组合对象和单个对象的不同时。