前言
GOF设计模式分三大类:
- 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
- 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
- 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。
一、中介者模式
中介者模式(Mediator Pattern)
定义:用一个中介对象(中介者)来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。中介者模式又称为调停者模式。
解决问题:如何协调多个对象之间复杂的相互调用?
使用场景:
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
- 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
- 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
组成:
- Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
- ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,维持了对各个同事对象的引用。
- Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
- ConcreteColleague(具体同事类):它是抽象同事类的子类。每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信。在具体同事类中实现了在抽象同事类中声明的抽象方法。
补充说明:
- 中介者模式将一个网状的系统结构变成一个以中介者对象为中心的星形结构。在这个星形结构中,使用中介者对象与其他对象的一对多关系来取代原有对象之间的多对多关系
- 通过引入中介者来简化对象之间的复杂交互,中介者模式是迪米特法则的一个典型应用。
- 中介者类承担了以下两方面的职责:
- 中转作用(结构性)
- 协调作用(行为性)
优点:
- 使用中介者类来协调多个类/对象之间的交互,以达到降低系统耦合度的目的。
- 中介者模式简化了对象之间的交互
- 可以减少大量同事子类生成
缺点:
- 在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。
二、中介者模式示例
为了协调界面组件对象之间的复杂交互关系,使用中介者模式来设计客户信息管理窗口
- 为了确保系统具有更好的灵活性和可扩展性,需要定义抽象中介者和抽象组件类,其中抽象组件类是所有具体组件类的公共父类。
- Component充当抽象同事类,Button、List、ComboBox和TextBox充当具体同事类,Mediator充当抽象中介者类,ConcreteMediator充当具体中介者类。ConcreteMediator维持了对具体同事类的引用
"""抽象中介者"""
class Mediator:
def component_changed(self, c: "Component"):
raise NotImplementedError
"""具体中介者"""
class ConcreteMediator(Mediator):
def __init__(self):
self.add_button: Button = None
self.my_list: MyList = None
self.user_name_text_box: TextBox = None
self.cb: ComboBox = None
def component_changed(self, c):
# 封装同事对象之间的交互
if c == self.add_button:
# 单击按钮
print("——单击增加按钮——")
self.my_list.update()
self.cb.update()
self.user_name_text_box.update()
elif c == self.my_list:
# 从列表框中选择客户
print("——从列表框中选择客户——")
self.cb.select()
self.user_name_text_box.set_text()
elif c == self.cb:
# 从组合框中选择客户
print("——从组合框中选择客户——")
self.cb.select()
self.user_name_text_box.set_text()
"""抽象同事类/抽象组件类"""
class Component:
def __init__(self):
self.mediator: Mediator = None
def changed(self):
# 转发调用
self.mediator.component_changed(self)
def update(self):
raise NotImplementedError
"""具体同事类/具体组件类"""
class Button(Component):
def update(self):
# 按钮不产生响应
pass
class TextBox(Component):
def update(self):
print("客户信息增加成功后文本框清空。")
def set_text(self):
print("文本框显示《三国演义》。")
class ComboBox(Component):
def update(self):
print("组合框增加一项:《红楼梦》")
def select(self):
print("组合框选中项:《三国演义》")
class MyList(Component):
def update(self):
print("列表框增加一项:《红楼梦》")
def select(self):
print("列表框选中项:《三国演义》")
- 客户端代码
if __name__ == "__main__":
# 定义中介者对象
mediator = ConcreteMediator()
# 定义同事对象
add_button = Button()
my_list = MyList()
cb = ComboBox()
user_name_tb = TextBox()
add_button.mediator = mediator
my_list.mediator = mediator
cb.mediator = mediator
user_name_tb.mediator = mediator
mediator.add_button = add_button
mediator.my_list = my_list
mediator.cb = cb
mediator.user_name_text_box = user_name_tb
add_button.changed()
print("#" * 10)
my_list.changed()
- 输出结果
——单击增加按钮——
列表框增加一项:《红楼梦》
组合框增加一项:《红楼梦》
客户信息增加成功后文本框清空。
##########
——从列表框中选择客户——
组合框选中项:《三国演义》
文本框显示《三国演义》。
您正在阅读的是《设计模式Python版》专栏!关注不迷路~