組合模式
1、內容
對於樹形結構,當容器物件(如資料夾)的某一個方法被呼叫時,將遍歷整個樹形結構,尋找也包含這個方法的成員物件(可以是容器物件,也可以是葉子物件)並呼叫執行,牽一而動百,其中使用了遞迴呼叫的機制來對整個結構進行處理。由於容器物件和葉子物件在功能上的區別,在使用這些物件的程式碼中必須有區別地對待容器物件和葉子物件,而實際上大多數情況下我們希望一致地處理它們,因為對於這些物件的區別對待將會使得程式非常複雜。組合模式為解決此類問題而誕生,它可以讓葉子物件和容器物件的使用具有一致性。
2、角色
抽象元件 葉子元件 複合元件 客戶端
3、使用場景
表示物件的‘部分-整體’層次結構(特別是結構是遞迴的) 希望使用者忽略組合物件與單個物件的不同,使用者統一的使用組合結構中的所有物件
**4、優點 **
定義了包含基本物件和組合的類層次結構 簡化客戶端程式碼,即客戶端可以一致地使用組合物件和單個物件 更容易增加新型別的元件
5、缺點
很難限制組合中的元件
6、程式碼示例
from abc import abstractmethod,ABCMeta
class Graphic(metaclass=ABCMeta):
'''圖形類'''
@abstractmethod
def draw(self):
pass
@abstractmethod
def add(self,graphic):
pass
@abstractmethod
def getchildren(self,graphic):
pass
class Point(Graphic):
'''點'''
def __init__(self,x,y):
self.x = x
self.y = y
def draw(self):
print(self)
def add(self,graphic):
raise TypeError
def getchildren(self,graphic):
raise TypeError
def __str__(self):
return '點(%s,%s)' %(self.x,self.y)
class Line(Graphic):
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
def draw(self):
print(self)
def add(self, graphic):
raise TypeError
def getchildren(self):
raise TypeError
def __str__(self):
return "線段[%s, %s]" % (self.p1, self.p2)
class Picture(Graphic):
def __init__(self):
self.children = []
def add(self,graphic):
self.children.append(graphic)
def getchildren(self, graphic):
'''返回列表裡面的孩子'''
return self.children
def draw(self):
print('======複合圖形======')
for i in self.children:
print('所有的孩子們',i)
i.draw()
print('======end=========')
pic1 = Picture()
pic1.add(Point(2,3))
pic1.add(Line(Point(1,2), Point(4,5)))
pic1.add(Line(Point(0,1), Point(2,1)))
pic2 = Picture()
pic2.add(Point(-2,-1))
pic2.add(Line(Point(0,0), Point(1,1)))
pic = Picture()
pic.add(pic1)
pic.add(pic2)
pic.draw()
.draw這個函式對外表現一致,所有的都呼叫這個方法、
複製程式碼