设计模式Python版 中介者模式

news/2025/2/24 11:16:50

文章目录


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、中介者模式

中介者模式(Mediator Pattern)

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

  • 解决问题:如何协调多个对象之间复杂的相互调用?

  • 使用场景:

    • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
    • 一个对象由于引用了其他很多对象并且直接和这些对象通信,导致难以复用该对象。
    • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。
  • 组成:

    • Mediator(抽象中介者):它定义一个接口,该接口用于与各同事对象之间进行通信。
    • ConcreteMediator(具体中介者):它是抽象中介者的子类,通过协调各个同事对象来实现协作行为,维持了对各个同事对象的引用。
    • Colleague(抽象同事类):它定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
    • ConcreteColleague(具体同事类):它是抽象同事类的子类。每一个同事对象在需要和其他同事对象通信时,先与中介者通信,通过中介者来间接完成与其他同事类的通信。在具体同事类中实现了在抽象同事类中声明的抽象方法。
  • 补充说明:

    • 中介者模式将一个网状的系统结构变成一个以中介者对象为中心的星形结构。在这个星形结构中,使用中介者对象与其他对象的一对多关系来取代原有对象之间的多对多关系
    • 通过引入中介者来简化对象之间的复杂交互,中介者模式是迪米特法则的一个典型应用。
    • 中介者类承担了以下两方面的职责:
      • 中转作用(结构性)
      • 协调作用(行为性)
  • 优点:

    • 使用中介者类来协调多个类/对象之间的交互,以达到降低系统耦合度的目的。
    • 中介者模式简化了对象之间的交互
    • 可以减少大量同事子类生成
  • 缺点:

    • 在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。

在这里插入图片描述

二、中介者模式示例

为了协调界面组件对象之间的复杂交互关系,使用中介者模式来设计客户信息管理窗口

  • 为了确保系统具有更好的灵活性和可扩展性,需要定义抽象中介者和抽象组件类,其中抽象组件类是所有具体组件类的公共父类。
  • Component充当抽象同事类,Button、List、ComboBox和TextBox充当具体同事类,Mediator充当抽象中介者类,ConcreteMediator充当具体中介者类。ConcreteMediator维持了对具体同事类的引用
python">"""抽象中介者"""


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("列表框选中项:《三国演义》")

在这里插入图片描述

  • 客户端代码
python">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版》专栏!关注不迷路~


http://www.niftyadmin.cn/n/5864254.html

相关文章

单入单出队列性能优化(Lock-Free)

摘要:文中首先介绍了有锁线程安全循环队列的基本实现,然后探讨了使用原子变量实现 Lock-Free 队列的优势,能够减少线程之间的数据竞争。接着,介绍了数据对齐的策略,以降低伪共享的概率,随后引入了索引缓存来…

C++初阶——简单实现list

目录 1、前言 2、List.h 3、Test.cpp 1、前言 1. 简单实现std::list,重点:迭代器,模板类,运算符重载。 2. 并不是,所有的类,都需要深拷贝,像迭代器类模板,只是用别的类的资源&am…

leetcode day20 滑动窗口209+904

209 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。 示例 1&#…

【Python量化金融实战】-第1章:Python量化金融概述:1.4 开发环境搭建:Jupyter Notebook、VS Code、PyCharm

在量化金融开发中,选择合适的开发环境至关重要。本章介绍三种主流工具:Jupyter Notebook(交互式分析)、VS Code(轻量级编辑器)、PyCharm(专业IDE),并通过实战案例展示其应…

UniApp SelectorQuery 讲解

一、SelectorQuery简介 在UniApp中,SelectorQuery是一个非常强大的工具,它允许开发者查询节点信息。通过这个API,我们可以获取到页面元素的尺寸、位置、滚动条位置等信息。这在处理动态布局、动画效果或是用户交互时尤为重要。 二、基本使用…

【Git 学习笔记_27】DIY 实战篇:利用 DeepSeek 实现 GitHub 的 GPG 密钥创建与配置

文章目录 1 前言2 准备工作3 具体配置过程3.1. 本地生成 GPG 密钥3.2. 导出 GPG 密钥3.3. 将密钥配置到 Git 中3.4. 测试提交 4 问题排查记录5 小结与复盘 1 前言 昨天在更新我的第二个 Vim 专栏《Mastering Vim (2nd Ed.)》时遇到一个经典的 Git 操作问题:如何在 …

亚马逊云科技MySQL托管服务:Amazon RDS for MySQL的技术优势与成本优化实践

引言: 在数字化转型的浪潮中,数据库作为企业核心业务的“中枢神经”,其稳定性、性能及成本直接影响企业的运营效率和竞争力。然而,自建MySQL数据库的复杂性、运维成本高企、扩展性不足等问题,始终是开发者与…

【人工智能】蓝耘智算平台盛大发布DeepSeek满血版:开创AI推理体验新纪元

📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀ 蓝耘智算平台 蓝耘智算平台核心技术与突破元生代推理引擎快速入门:三步调用大模型接口,OpenAI SDK无缝兼容实战用例文…