大话设计模式:第25章 中介者模式

第25章:中介者模式

中介者模式

中介者(mediator)模式,用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

中介者模式又称调停者模式,是指中间人或者调停者的意思。

将一个系统分割成许多对象通常可以增加其可复用性,但是对象间相互连接的激增又会降低其可复用性了。因为大量的连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,所以,对系统的行为进行任何较大的改动就十分困难。

根据迪米特法则,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。通过中介者对象,可以将系统的网状结构变成以中介者为中心的星形结构。每个具体对象不再通过直接联系与另一个对象发生相互作用,而是通过中介者对象与另一个对象发生相互作用。中介者对象的设计,使得系统的结构不会因为新对象的引入造成大量的修改工作。

在这里插入图片描述

Colleague是抽象同事类;ConcreteColleague是具体同事类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象;Mediator是抽象中介者,定义了同事对象到中介者对象的接口;ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接收消息,向具体同事对象发出命令。

Mediator类,抽象中介者类

在这里插入图片描述

Colleague类,抽象同事类

在这里插入图片描述

ConcreteMediator类,具体中介者类

在这里插入图片描述

ConcreteColleague1ConcreteColleague2等各种同事对象

在这里插入图片描述

客户端调用

在这里插入图片描述

中介者模式优缺点

中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了“多对多”交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。

  • 中介者模式的优点

    1. Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator

    2. 由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。

  • 中介者模式的缺点

    1. 由于ConcreteMediator控制了集中化,于是就把交互复杂性变为了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。

中介者模式的优点来自集中控制,其缺点也是它,使用时是注意。

中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。 例:用.NET编写的Windows应用程序中的窗体Form或Web网站程序的aspx就是典型的中介者。

中介者模式示例

任务:安理会中介

在这里插入图片描述

from abc import ABCMeta, abstractmethod
from typing import Text
class UnitedNations(metaclass=ABCMeta):
    """
    联合国机构(Mediator)类
    """
    @abstractmethod
    def declare(self, message: Text, colleage: object) -> None:
        pass
    
class Country(metaclass=ABCMeta):
    """
    国家(Colleague)类
    """
    def __init__(self, mediator: UnitedNations) -> None:
        self._mediator = mediator
class USA(Country):
    """
    美国(ConcreteColleague1)类
    """
    def declare(self, message: Text) -> None:
        """
        声明
        """
        self._mediator.declare(message, self)
        
    def get_message(self, message: Text) -> None:
        """
        获得消息
        """
        print("美国获得对方信息:" + message)
        
class Iraq(Country):
    """
    伊拉克(ConcreteColleague2)类
    """
    def declare(self, message: Text) -> None:
        """
        声明
        """
        self._mediator.declare(message, self)
        
    def get_message(self, message: Text) -> None:
        """
        获得消息
        """
        print("伊拉克获得对方信息:" + message)
        
class UnitedNationsSecurityCouncil(UnitedNations):
    """
    联合国安理会(ConcreteMediator)类
    """
    def __init__(self) -> None:
        self.__colleague1 = None
        self.__colleague2 = None
        
    @property
    def colleague1(self) -> Country:
        return self.__colleague1
    @colleague1.setter
    def colleague1(self, value: Country) -> None:
        self.__colleague1 = value
    
    @property
    def colleague2(self) -> Country:
        return self.__colleague2
    @colleague2.setter
    def colleague2(self, value: Country) -> None:
        self.__colleague2 = value
        
    def declare(self, message: Text, colleage: object) -> None:
        if colleage is self.__colleague1:
            self.__colleague2.get_message(message)
        elif colleage is self.__colleague2:
            self.__colleague1.get_message(message)
        else:
            pass
    
# 客户端调用

if __name__ == "__main__":
    
    unsc = UnitedNationsSecurityCouncil()
    
    usa = USA(unsc)
    iraq = Iraq(unsc)
    
    unsc.colleague1 = usa
    unsc.colleague2 = iraq
    
    usa.declare("不准研制核武器,否则要发动战争!")
    iraq.declare("我们没有核武器,也不怕侵略。")
伊拉克获得对方信息:不准研制核武器,否则要发动战争!
美国获得对方信息:我们没有核武器,也不怕侵略。

猜你喜欢

转载自blog.csdn.net/zhaoyin214/article/details/106025755