组合模式(Composite)是用于將目前对象視為整体而把要納入協同作業之其它对象(*可能為一個或一组)視為部份,此種模式會依树形结构来表現其組織层次,在此树型结构下客户端可透過對目前對象之处理即可操控其下組織之組成對象,實作上整体對象只要提供接口供外界來調用(*通常定義在抽象基類中),且内部須配有list型態之集合属性來存放部份對象(*通常定義在繼承之具体子類中),在使用场景上只要須具備树形結構之菜单、文件夹的管理均可以此模式來設計。
示例:
class Company: #抽象基类(*含接口定義)
name = ''
def __init__(self, name):
self.name = name
def Add(self, company):
pass
def Remove(self, company):
pass
def Display(self, depth):
pass
def LineOfDuty(self):
pass
class ConcreteCompany(Company): #具体子類:整体對象(whole)
childrenCompany = None #此是作為納入其它部份對象之集合屬性
def __init__(self, name):
Company.__init__(self,name) #調用基類之初始化函式
self.childrenCompany = [] #在初始化時要決定集合屬性之初值條件
def Add(self, company):
self.childrenCompany.append(company)
def Remove(self, company):
self.childrenCompany.remove(company)
def Display(self, depth): #定義函式時別忘了要加上self,此depth是決定树型結構之層次
print('-'*depth + self.name)
for component in self.childrenCompany:
component.Display(depth+2) #調用函式時不用加上self
def LineOfDuty(self):
for component in self.childrenCompany:
component.LineOfDuty()
class HRDepartment(Company): #具体子類:部份對象(component)
def __init__(self, name):
Company.__init__(self,name)
def Display(self, depth):
print('-'*depth + self.name)
def LineOfDuty(self):
print('%s\t员工招聘培训管理' % self.name)
class FinanceDepartment(Company): #具体子類:部份對象(component)
def __init__(self, name):
Company.__init__(self,name)
def Display(self, depth):
print('-'*depth + self.name)
def LineOfDuty(self):
print('%s\t公司财务收支管理' % self.name)
def clientUI(): #以函式來定義client端
root = ConcreteCompany('北京总公司') #whole
root.Add(HRDepartment('总公司人力资源部')) #加入component
root.Add(FinanceDepartment('总公司财务部'))
comp = ConcreteCompany('华东分公司') #whole
comp.Add(HRDepartment('华东分公司人力资源部')) #加入component
comp.Add(FinanceDepartment('华东分公司财务部'))
root.Add(comp)
comp1 = ConcreteCompany('南京办事处')
comp1.Add(HRDepartment('南京办事处人力资源部'))
comp1.Add(FinanceDepartment('南京办事处财务部'))
comp.Add(comp1)
comp2 = ConcreteCompany('杭州办事处')
comp2.Add(HRDepartment('杭州办事处人力资源部'))
comp2.Add(FinanceDepartment('杭州办事处财务部'))
comp.Add(comp2)
print('-------公司结构图-------')
root.Display(1)
print('\n-------职责-------')
root.LineOfDuty()
if __name__ == '__main__':
clientUI();
輸出:
-------公司结构图-------
-北京总公司
---总公司人力资源部
---总公司财务部
---华东分公司
-----华东分公司人力资源部
-----华东分公司财务部
-----南京办事处
-------南京办事处人力资源部
-------南京办事处财务部
-----杭州办事处
-------杭州办事处人力资源部
-------杭州办事处财务部
-------职责-------
总公司人力资源部 员工招聘培训管理
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘培训管理
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘培训管理
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘培训管理
杭州办事处财务部 公司财务收支管理
思考邏輯:一棵树下會有很多树枝,每个树枝下會有很多叶子,只要取树便可得到树枝,也就能得到所有叶子了。