9-Python與設計模式--組合模式
一、公司結構組織
每一個公司都有自己的組織結構,越是大型的企業,其組織結構就會越複雜。大多數情況下,公司喜歡用“樹形”結構來組織複雜的公司人事關係和公司間的結構關係。一般情況下,根結點代表公司的最高行政權利單位,分支節點表示一個個部門,而葉子結點則會用來代表每一個員工。每一個結點的子樹,表示該結點代表的部門所管理的單位。假設一個具有HR部門,財務部門和研發部門,同時在全國有分支公司的總公司,其公司結構,可以表示成如下邏輯:
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 listDuty(self): pass class ConcreteCompany(Company): 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): print'-'*depth + self.name for component in self.childrenCompany: component.display(depth+1) def listDuty(self): for component in self.childrenCompany: component.listDuty() class HRDepartment(Company): def __init__(self, name): Company.__init__(self,name) def display(self, depth): print '-'*depth + self.name def listDuty(self): #履行職責 print '%s\t Enrolling & Transfering management.' % self.name class FinanceDepartment(Company): def __init__(self, name): Company.__init__(self,name) def display(self, depth): print "-" * depth + self.name def listDuty(self): #履行職責 print '%s\tFinance Management.'%self.name class RdDepartment(Company): def __init__(self,name): Company.__init__(self,name) def display(self, depth): print "-"*depth+self.name def listDuty(self): print "%s\tResearch & Development."% self.name
在該例中,公司結構抽象僅考慮公司(ConcreteCompany)和部門(Department),公司有子公司的可能性,公司也有自己的部門,部門是最終的葉子結點。
假設總公司下設東邊的分公司一個,東邊的分公司下設東北公司和東南公司,顯示公司層級,並羅列這些的公司中各部門的職責,可以構建如下業務場景:
if __name__=="__main__": root = ConcreteCompany('HeadQuarter') root.add(HRDepartment('HQ HR')) root.add(FinanceDepartment('HQ Finance')) root.add(RdDepartment("HQ R&D")) comp = ConcreteCompany('East Branch') comp.add(HRDepartment('East.Br HR')) comp.add(FinanceDepartment('East.Br Finance')) comp.add(RdDepartment("East.Br R&D")) root.add(comp) comp1 = ConcreteCompany('Northast Branch') comp1.add(HRDepartment('Northeast.Br HR')) comp1.add(FinanceDepartment('Northeast.Br Finance')) comp1.add(RdDepartment("Northeast.Br R&D")) comp.add(comp1) comp2 = ConcreteCompany('Southeast Branch') comp2.add(HRDepartment('Southeast.Br HR')) comp2.add(FinanceDepartment('Southeast.Br Finance')) comp2.add(RdDepartment("Southeast.Br R&D")) comp.add(comp2) root.display(1) root.listDuty()
列印如下:
-HeadQuarter
--HQ HR
--HQ Finance
--HQ R&D
--East Branch
---East.Br HR
---East.Br Finance
---East.Br R&D
---Northast Branch
----Northeast.Br HR
----Northeast.Br Finance
----Northeast.Br R&D
---Southeast Branch
----Southeast.Br HR
----Southeast.Br Finance
----Southeast.Br R&D
HQ HR Enrolling & Transfering management.
HQ Finance Finance Management.
HQ R&D Research & Development.
East.Br HR Enrolling & Transfering management.
East.Br Finance Finance Management.
East.Br R&D Research & Development.
Northeast.Br HR Enrolling & Transfering management.
Northeast.Br Finance Finance Management.
Northeast.Br R&D Research & Development.
Southeast.Br HR Enrolling & Transfering management.
Southeast.Br Finance Finance Management.
Southeast.Br R&D Research & Development.
二、組合模式
組合模式也叫作部分-整體模式,其定義如下:將物件組合成樹形結構以表示“部分”和“整體”的層次結構,使得使用者對單個物件和組合物件的使用具有一致性。
三、組合模式的優點和使用場景
優點:
1、節點增加和減少是非常自由和方便的,這也是樹形結構的一大特點;
2、所有節點,不管是分支節點還是葉子結點,不管是呼叫一個結點,還是呼叫一個結點群,都是非常方便的。
使用場景:
1、維護部分與整體的邏輯關係,或者動態呼叫整體或部分的功能介面,可以考慮使用組合模式。例如,非常多的作業系統(如Linux)都把檔案系統設計成樹形結構,再比如說分散式應用中藉助Zookeeper,也可以組織和呼叫分散式叢集中的結點功能。
四、組合模式的缺點
1、由於葉子結點和分支結點直接使用了實現類,而不方便使用抽象類,這大大限制了介面的影響範圍;若結點介面發生變更,對系統造成的風險會比較大。