github地址:https://github.com/cheesezh/python_design_patternspython
聯合國在世界上就是中介者的角色,各國之間的關係複雜,相似不一樣的對象和對象之間的關係,這就要求對象之間須要知道其餘全部對象,儘管將一個系統分割成許多對象一般能夠增長其可複用性,可是對象間相互鏈接的激增優惠下降其可複用性。大量的鏈接使得一個對象不可能在沒有其餘對象的支持下工做,系統表現爲一個不可分割的總體,因此,對系統的行爲進行任何較大的改動就十分困難了。git
這裏能夠應用「迪米特法則」,若是兩個類沒必要彼此直接通信,那麼這兩個類就不該該發生直接的相互做用。若是其中一個類須要調用另外一個類的某一種方法的話,能夠經過第三者轉發這個調用。也就是說,國與國之間的關係,徹底能夠經過聯合國這個中介者來維持,而沒必要直接通訊。github
中介者模式,用一箇中介對象來封裝一系列的對象交互。中介者使各個對象不須要顯示的相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。[DP]安全
中介者模式主要包括如下幾個類:設計
from abc import ABCMeta, abstractmethod class Mediator(): """ 抽象中介者 """ __metaclass__ = ABCMeta @abstractmethod def send(self, message, colleague): """ 定義一個抽象的發送消息方法,獲得同事對象和發送消息 """ pass class Colleague(): """ 抽象同事類 """ __metaclass__ = ABCMeta def __init__(self, mediator): """ 構造方法,獲得中介者對象 """ self.mediator = mediator class ConcreteMediator(Mediator): """ 具體中介者 """ def __init__(self): """ 須要瞭解全部的具體同事對象 """ self.colleague1 = None self.colleague2 = None def send(self, message, colleague): """ 重寫發送消息的方法,根據對象做出選擇判斷,通知具體同事對象 """ if colleague == self.colleague1: self.colleague2.notify(message) else: self.colleague1.notify(message) class ConcreteColleague1(Colleague): """ 具體同事類1 """ def send(self, message): self.mediator.send(message, self) def notify(self, message): print("同事1獲得消息:",message) class ConcreteColleague2(Colleague): """ 具體同事類2 """ def send(self, message): self.mediator.send(message, self) def notify(self, message): print("同事2獲得消息:",message) def main(): m = ConcreteMediator() """ 讓兩個具體同事類認識中介者對象 """ c1 = ConcreteColleague1(m) c2 = ConcreteColleague2(m) """ 讓中介者認識各個具體同事類 """ m.colleague1 = c1 m.colleague2 = c2 """ 具體同事類對象發送消息都是經過中介者轉發 """ c1.send("吃飯了嗎?") c2.send("還沒,你請客麼?") main()
同事2獲得消息: 吃飯了嗎? 同事1獲得消息: 還沒,你請客麼?
因爲有了Mediator,使得ConcreteColleague1和ConcreteColleague2在發送消息和接收消息時實際上是經過中介者來完成,這就減小了它們之間的耦合度。code
用程序模擬,美國和伊拉克之間的對話都是經過聯合國安理會做爲中介來完成。對象
from abc import ABCMeta, abstractmethod class UnitedNations(): """ 聯合國機構,抽象中介者 """ __metaclass__ = ABCMeta @abstractmethod def send(self, message, colleague): """ 定義一個抽象的發送消息方法,獲得同事對象和發送消息 """ pass class Country(): """ 國家類,抽象同事類 """ __metaclass__ = ABCMeta def __init__(self, mediator): """ 構造方法,獲得中介者對象 """ self.mediator = mediator class UnitedNationsSecurityCouncil(Mediator): """ 聯合國安全理事會,具體中介者 """ def __init__(self): """ 須要瞭解全部的具體同事對象 """ self.colleague1 = None self.colleague2 = None def send(self, message, colleague): """ 重寫發送消息的方法,根據對象做出選擇判斷,通知具體同事對象 """ if colleague == self.colleague1: self.colleague2.notify(message) else: self.colleague1.notify(message) class USA(Colleague): """ 美國,具體同事類1 """ def send(self, message): self.mediator.send(message, self) def notify(self, message): print("美國 獲得消息:",message) class Iraq(Colleague): """ 伊拉克,具體同事類2 """ def send(self, message): self.mediator.send(message, self) def notify(self, message): print("伊拉克 獲得消息:",message) def main(): m = UnitedNationsSecurityCouncil() """ 讓兩個具體同事類認識中介者對象 """ c1 = USA(m) c2 = Iraq(m) """ 讓中介者認識各個具體同事類 """ m.colleague1 = c1 m.colleague2 = c2 """ 具體同事類對象發送消息都是經過中介者轉發 """ c1.send("吃飯了嗎?") c2.send("還沒,你請客麼?") main()
伊拉克 獲得消息: 吃飯了嗎? 美國 獲得消息: 還沒,你請客麼?
ConcretMediator這個類必需要知道全部ConcreteCollegue,這就使得ConcreteMediator責任太多,若是它出現問題,則整個系統都會出現問題。接口
中介者模式很容易在系統中應用,也很容易在系統中誤用。當系統出現「多對多」交互複雜的對象羣時,不要急於使用中介者模式,而要先反思你的系統在設計上是否合理。ci
中介者模式的優勢:get
中介者模式的缺點: