組合模式:將對象組合成熟型結構一表示‘部分-整體’的層次結構。組合模式使得用戶對單個對象的組合對象的使用具有一致性。具體來講就是,樹根和樹枝和樹葉都是統一對待的。樹枝和樹葉繼承於樹根。
什麼時候用組合模式?
當需求中是體現部分與整體的層次結構式,以及你希望用戶可以忽略組合對象與單個對象的不同,統一使用組合結構中的所有對象時,就應該考慮用組合模式。好了,上代碼。
from abc import ABCMeta, abstractmethod
class Company(metaclass=ABCMeta):
def __init__(self, name):
self.name = name
@abstractmethod
def add(self, company):
pass
@abstractmethod
def remove(self, company):
pass
@abstractmethod
def display(self, depth):
pass
@abstractmethod
def line_of_duty(self):
pass
class ConcreteCompany(Company):
def __init__(self, name):
super().__init__(name)
self.children = []
def add(self, company):
self.children.append(company)
def remove(self, company):
self.children.remove(company)
def display(self, depth):
print('-'*depth + "Company {0}".format(self.name))
for company in self.children:
company.display(depth + 2)
def line_of_duty(self):
for company in self.children:
company.line_of_duty()
class HRDepartment(Company):
def __init__(self, name):
super().__init__(name)
def add(self, company):
pass
def remove(self, company):
pass
def display(self, depth):
print('-'*depth + self.name)
def line_of_duty(self):
print("{0} This department is responsible for recruiting employees".format(self.name))
class FinanceDepartment(Company):
def __init__(self, name):
super().__init__(name)
def add(self, company):
pass
def remove(self, company):
pass
def display(self, depth):
print('-'*depth + self.name)
def line_of_duty(self):
print("{0} This department is responsible for managing the money".format(self.name))
if __name__ == "__main__":
headquarter = ConcreteCompany("Headquarter")
headquarter.add(HRDepartment("Root HR"))
headquarter.add(FinanceDepartment("Root Finance"))
south_subsidy = ConcreteCompany("SouthSubsidy")
south_subsidy.add(HRDepartment("SouthSubsidy HR Department"))
south_subsidy.add(FinanceDepartment("SouthSubsidy Finance Department"))
headquarter.add(south_subsidy)
north_subsidy = ConcreteCompany("NorthSubsidy")
north_subsidy.add(HRDepartment("NorthSubsidy HR Department"))
north_subsidy.add(FinanceDepartment("NorthSubsidy Finance Department"))
headquarter.add(north_subsidy)
headquarter.display(1)
headquarter.line_of_duty()
這段代碼中,優點浪費的是,具體的部門類,也就是樹葉,裏邊爲了統一性會有一部分的代碼沒有實現。也可以把這些去掉。在Comany類中不寫這兩個接口,只在ConcreteCompany 類中實現add remove等操作,但是這樣在使用這些類的時候, 由於樹葉和樹枝接口不同,就需要有一些判斷。