中介者模式

简介: 中介者模式标签 : Java与设计模式面向对象设计鼓励将行为分布到各个对象中, 这种分布可能会导致对象间有许多连接.

中介者模式

标签 : Java与设计模式


面向对象设计鼓励将行为分布到各个对象中, 这种分布可能会导致对象间有许多连接. 在最坏的情况下, 每一个对象都需要知道其他所有对象.
虽然将一个系统分割成许多对象可增强可复用性, 但是对象间相互连接的激增又会降低其可复用性. 大量的连接关系使得一个对象不可能在没有其他对象的协助下工作(系统表现为一个不可分割的整体), 此时再对系统行为进行任何较大改动就十分困难. 因为行为被分布在许多对象中, 结果是不得不定义很多子类以定制系统的行为. 由此我们引入了中介者对象Mediator:

通过中介者对象, 可以将网状结构的系统改造成以中介者为中心的星型结构, 每个具体对象不再与另一个对象直接发生关系, 而是通过中介者对象从中调停.中介者对象的引入,也使得系统结构不会因新对象的引入造成大量的修改.


中介者模式

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

(图片来源: 设计模式: 可复用面向对象软件的基础)

  • Tips: 各Colleague只知道Mediator的存在, 并不需要知道其他Colleague是否存在(不然怎么解耦呢), 它只需将消息发送给Mediator, 然后由Mediator转发给其他Colleague(由Mediator存储所有Colleague关系, 也只有Mediator知道有多少/哪些Colleague).

模式实现

联合国转发各国声明, 调停各国关系: 
各国向联合国安理会发送和接收消息, 安理会在各国间'适当地'转发请求以实现协作行为:


Colleague

抽象同事类, 定义各同事的公有方法:

/**
 * @author jifang
 * @since 16/8/28 下午4:22.
 */
public abstract class Country {

    protected UnitedNations mediator;

    private String name;

    public Country(UnitedNations mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    protected abstract void declare(String msg);

    protected abstract void receive(String msg);
}

ConcreteColleague

具体同事类:

  • 每一个同事类都知道它的中介者对象.
  • 每一个同事对象在需与其他同事通信时, 与它的中介者通信.
class USA extends Country {

    public USA(UnitedNations mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void declare(String msg) {
        mediator.declare(this, msg);
    }

    @Override
    public void receive(String msg) {
        System.out.println("美国接收到: [" + msg + "]");
    }
}

class Iraq extends Country {

    public Iraq(UnitedNations mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void declare(String msg) {
        mediator.declare(this, msg);
    }

    @Override
    public void receive(String msg) {
        System.out.println("伊拉克接收到: [" + msg + "]");
    }
}

class China extends Country {

    public China(UnitedNations mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void declare(String msg) {
        mediator.declare(this, msg);
    }

    @Override
    public void receive(String msg) {
        System.out.println("中国接收到: [" + msg + "]");
    }
}

Mediator

抽象中介者: 定义一个接口用于与各同事对象通信:

public abstract class UnitedNations {

    protected List<Country> countries = new LinkedList<>();

    public void register(Country country) {
        countries.add(country);
    }

    public void remove(Country country) {
        countries.remove(country);
    }

    protected abstract void declare(Country country, String msg);
}

ConcreteMediator

具体中介者:

  • 了解并维护它的各个同事;
  • 通过协调各同事对象实现协作行为(从同事接收消息, 向具体同事发出命令).
class UnitedNationsSecurityCouncil extends UnitedNations {

    /**
     * 安理会在中间作出调停
     *
     * @param country
     * @param msg
     */
    @Override
    protected void declare(Country country, String msg) {
        for (Country toCountry : countries) {
            if (!toCountry.equals(country)) {
                String name = country.getName();
                toCountry.receive(name + "平和的说: " + msg);
            }
        }
    }
}

如果不存在扩展情况, 那么Mediator可与ConcreteMediator合二为一.

  • Client
public class Client {

    @Test
    public void client() {
        UnitedNations mediator = new UnitedNationsSecurityCouncil();

        Country usa = new USA(mediator, "美国");
        Country china = new China(mediator, "中国");
        Country iraq = new Iraq(mediator, "伊拉克");

        mediator.register(usa);
        mediator.register(china);
        mediator.register(iraq);

        usa.declare("我要打伊拉克, 谁管我跟谁急!!!");
        System.out.println("----------");
        china.declare("我们强烈谴责!!!");
        System.out.println("----------");
        iraq.declare("来呀, 来互相伤害呀!!!");
    }
}

小结

Mediator的出现减少了各Colleague之间的耦合, 使得可以独立改变和复用各ColleagueMediator, 由于把对象如何协作进行了抽象将中介作为一个独立的概念并将其封装在一个对象中, 这样关注的焦点就从对象各自本身的行为转移到它们之间的交互上来, 从而可以站在一个更宏观的角度去看待系统.

  • 适用性
    中介者模式很容易在系统中应用, 也很容易在系统中误用. 当系统出现了“多对多”交互复杂的对象群时, 不要急于使用中介者, 最好首先先反思系统的设计是否是合理. 由于ConcreteMediator控制了集中化, 于是就把交互复杂性变成了中介者的复杂性, 使得中介者变得比任一个ConcreteColleague都复杂. 在下列情况下建议使用中介者模式:

    • 一组对象以定义良好但复杂的方式进行通信. 产生的相互依赖关系结构混乱且难以理解.
    • 一个对象引用其他很多对象并且直接与这些对象通信, 导致难以复用该对象.
    • 想定制一个分布在多个类中的行为, 而又不想生成太多的子类.
  • 相关模式

    • Facade与中介者的不同之处在于它是对一个对象子系统进行抽象, 从而提供了一个更为方便的接口, 它的协议是单向的, 即Facade对象对这个子系统类提出请求, 但反之则不可. 相反, Mediator提供了各Colleague对象不支持或不能支持的协作行为, 而且协议是多向的.
    • Colleague可使用Observer模式Mediator通信.

参考
设计模式: 可复用面向对象软件的基础
大话设计模式
高淇讲设计模式
设计模式读书笔记–中介者模式
设计模式 ( 十五 ) 中介者模式Mediator(对象行为型)

目录
相关文章
|
4月前
|
Kubernetes Devops 应用服务中间件
基于 Azure DevOps 与阿里云 ACK 构建企业级 CI/CD 流水线
本文介绍如何结合阿里云 ACK 与 Azure DevOps 搭建自动化部署流程,涵盖集群创建、流水线配置、应用部署与公网暴露,助力企业高效落地云原生 DevOps 实践。
449 0
|
2天前
|
存储 JavaScript 前端开发
JavaScript基础
本节讲解JavaScript基础核心知识:涵盖值类型与引用类型区别、typeof检测类型及局限性、===与==差异及应用场景、内置函数与对象、原型链五规则、属性查找机制、instanceof原理,以及this指向和箭头函数中this的绑定时机。重点突出类型判断、原型继承与this机制,助力深入理解JS面向对象机制。(238字)
|
1天前
|
云安全 人工智能 安全
阿里云2026云上安全健康体检正式开启
新年启程,来为云上环境做一次“深度体检”
1470 6
|
3天前
|
安全 数据可视化 网络安全
安全无小事|阿里云先知众测,为企业筑牢防线
专为企业打造的漏洞信息收集平台
1304 2
|
3天前
|
缓存 算法 关系型数据库
深入浅出分布式 ID 生成方案:从原理到业界主流实现
本文深入探讨分布式ID的生成原理与主流解决方案,解析百度UidGenerator、滴滴TinyID及美团Leaf的核心设计,涵盖Snowflake算法、号段模式与双Buffer优化,助你掌握高并发下全局唯一ID的实现精髓。
319 160
|
3天前
|
人工智能 自然语言处理 API
n8n:流程自动化、智能化利器
流程自动化助你在重复的业务流程中节省时间,可通过自然语言直接创建工作流啦。
365 4
n8n:流程自动化、智能化利器
|
11天前
|
机器学习/深度学习 安全 API
MAI-UI 开源:通用 GUI 智能体基座登顶 SOTA!
MAI-UI是通义实验室推出的全尺寸GUI智能体基座模型,原生集成用户交互、MCP工具调用与端云协同能力。支持跨App操作、模糊语义理解与主动提问澄清,通过大规模在线强化学习实现复杂任务自动化,在出行、办公等高频场景中表现卓越,已登顶ScreenSpot-Pro、MobileWorld等多项SOTA评测。
1476 7
|
5天前
|
人工智能 API 开发工具
Skills比MCP更重要?更省钱的多!Python大佬这观点老金测了一周终于懂了
加我进AI学习群,公众号右下角“联系方式”。文末有老金开源知识库·全免费。本文详解Claude Skills为何比MCP更轻量高效:极简配置、按需加载、省90% token,适合多数场景。MCP仍适用于复杂集成,但日常任务首选Skills。推荐先用SKILL.md解决,再考虑协议。附实测对比与配置建议,助你提升效率,节省精力。关注老金,一起玩转AI工具。
|
1天前
|
Linux 数据库
Linux 环境 Polardb-X 数据库 单机版 rpm 包 安装教程
本文介绍在CentOS 7.9环境下安装PolarDB-X单机版数据库的完整流程,涵盖系统环境准备、本地Yum源配置、RPM包安装、用户与目录初始化、依赖库解决、数据库启动及客户端连接等步骤,助您快速部署运行PolarDB-X。
228 1
Linux 环境 Polardb-X 数据库 单机版 rpm 包 安装教程
|
12天前
|
人工智能 Rust 运维
这个神器让你白嫖ClaudeOpus 4.5,Gemini 3!还能接Claude Code等任意平台
加我进AI讨论学习群,公众号右下角“联系方式”文末有老金的 开源知识库地址·全免费
1342 17

热门文章

最新文章