[Python设计模式] 第25章 联合国维护世界和平——中介者模式

github地址:https://github.com/cheesezh/python_design_patternspython

题目背景

联合国在世界上就是中介者的角色,各国之间的关系复杂,相似不一样的对象和对象之间的关系,这就要求对象之间须要知道其余全部对象,尽管将一个系统分割成许多对象一般能够增长其可复用性,可是对象间相互链接的激增优惠下降其可复用性。大量的链接使得一个对象不可能在没有其余对象的支持下工做,系统表现为一个不可分割的总体,因此,对系统的行为进行任何较大的改动就十分困难了。git

这里能够应用“迪米特法则”,若是两个类没必要彼此直接通信,那么这两个类就不该该发生直接的相互做用。若是其中一个类须要调用另外一个类的某一种方法的话,能够经过第三者转发这个调用。也就是说,国与国之间的关系,彻底能够经过联合国这个中介者来维持,而没必要直接通讯。github

中介者模式

中介者模式,用一个中介对象来封装一系列的对象交互。中介者使各个对象不须要显示的相互引用,从而使其耦合松散,并且能够独立地改变它们之间的交互。[DP]安全

中介者模式主要包括如下几个类:设计

  • Colleague叫作抽象同事类,而ConcretColleague是具体同事类,每一个具体同事只知道本身的行为,而不了解其余同事类的状况,但它们却都认识中介者对象;
  • Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcretMediator是具体中介者对象,实现抽象类的方法,它须要知道全部具体同事类,并从具体同事接收消息,向具体同事对象发出命令。
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

  • Mediator的出现减小了各个Colleague的耦合,使得能够独立地改变和复用各个Colleague类和Mediator;
  • 因为把对象如何协做进行了抽象,将中介做为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自自己的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。

中介者模式的缺点:

  • 因为ConcreteMediator控制了集中化,因而就把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。
相关文章
相关标签/搜索