【浅谈设计模式】(19) 中介者模式 | 解耦还是解耦

前言

八小时内某生存,八小时外某发展。

继续走我们的设计模式,今天来到中介者模式专场。

一、概述

1.1 概念

中介者模式,从名字上我们再熟悉不过了,中介充当中间人的角色。对象与对象之间不再直接对接,通过中介来做桥梁,事实上也是这样的。目的嘛,就是解耦呗,貌似大多数设计模式搞的很复杂,就是为了解耦和程序的拓展性。

看看百科的定义:

中介者模式是为了"定义一个封装了对象间交互关系的对象"。这种方式避免了显式调用其他类,促进了类间的松耦合,并且使得类间交互关系本身可以单独修改

中介者模式:解决复杂功能应用之间的重复调用。

在这中间添加一层中介者包装服务,对外提供简单、通用、容易拓展的服务。

UML 的类图和时序图如上。

Mediator 是 中介的概念。Colleague 是同事的概念。

可以看到由 Mediator1 来通知具体同事做某些动作,而同事与同事之间并无关联关系。

看到这个类图里面用的角色居然是同事,说明 GoF 设计者也觉得同事之间的关系太过复杂,如果同事众多的话,两两组合,那就是网状结构了,同事之间互相耦合,如果采用中介者,所有同事都去找中介者,那如果某个同事离职了,就不用去改动其他同事的影响变化,只需要修改中介者就行。

这样,中介者就诞生了,我们的关系结构也变成星型结构。

由 "群魔乱舞" 形式转为 "朝拜天子"。

1.2 结构

再来看看类图,存在四种角色。

  • Mediator : 充当抽象中介者的概念,定义各个同事之间交互的接口

  • ConcreteMediator :充当具体中介者角色,实现 Mediator 的接口,必须要知道所有同事对象,且协调它们交互,因此,它需要依赖同事对象,可定义一个List来管理同事对象。

  • Colleague: 充当抽象同事角色,定义所有同事类的公共功能

  • ConcreteColleague:充当具体同事类,当需要与其他同事对象交互时,由中介者对象负责交互。

二、案例引入

就拿同事举例。

项目经理需要跨部门,跨公司协调项目进度。

参与方有:

  • 施工人员A

  • 技术人员B

  • 软件人员C

csharp 复制代码
abstract class Colleague {
    protected Mediator mediator;

    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }

    public abstract void sendMessage(String message);

    public abstract void receiveMessage(String message);
}

具体同事

typescript 复制代码
class ConcreteColleague1 extends Colleague {
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("施工人员 received message: " + message);
    }
}
typescript 复制代码
class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("技术人员 received message: " + message);
    }
}
typescript 复制代码
class ConcreteColleague3 extends Colleague {
    public ConcreteColleague3(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("软件人员 received message: " + message);
    }
}

中介者

arduino 复制代码
public interface Mediator {
    void sendMessage(String message, Colleague colleague);
}
typescript 复制代码
class ConcreteMediator implements Mediator {
    private List<Colleague> colleagues;

    public ConcreteMediator() {
        colleagues = new ArrayList<>();
    }

    public void addColleague(Colleague colleague) {
        colleagues.add(colleague);
    }

    @Override
    public void sendMessage(String message, Colleague colleague) {
        for (Colleague c : colleagues) {
            if (c != colleague) {
                c.receiveMessage(message);
            }
        }
    }
}

打印信息

csharp 复制代码
技术人员 received message: Hello from 施工人员
软件人员 received message: Hello from 施工人员
施工人员 received message: Hello from 技术人员
软件人员 received message: Hello from 技术人员
施工人员 received message: Hello from 软件人员
技术人员 received message: Hello from 软件人员

三、总结

优点:

  • 中介者模型将通过同事对象都封装到中介者对象中,从而使得同事对象之间松散耦合,同事对象可以独立的变化和复用,只需修改中介者即可。
  • 将一对多的关系转成一对一的关系

缺点:同事类太多的话,中介者的代码会非常复杂,难以维护

ok,再来区分下中介者模式与观察模式。

观察者模式中:一个对象要么是观察者,要么是被观察者,交互关系有条理。

中介者模式中:只有在参与者的交互关系非常错综复杂的时候,才会考虑中介模式。此外中介模式相当于一个管理者,可以维护不同参与者的通知顺序的控制,功能会更强。

中介者模式实际使用的场景貌似不多,目的就是为了解耦,而上图的星型结构的转变更是中介模式解耦的思想体现。

还剩最后三种了。下回见~

相关推荐
剑锋所指,所向披靡!1 天前
C++之类模版
java·jvm·c++
钟离墨笺1 天前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
Coder_Boy_1 天前
基于SpringAI的在线考试系统-0到1全流程研发:DDD、TDD与CICD协同实践
java·人工智能·spring boot·架构·ddd·tdd
sheji34161 天前
【开题答辩全过程】以 面向高校校园的物物交换系统设计与实现为例,包含答辩的问题和答案
java·eclipse
卓怡学长1 天前
m115乐购游戏商城系统
java·前端·数据库·spring boot·spring·游戏
2501_944526421 天前
Flutter for OpenHarmony 万能游戏库App实战 - 蜘蛛纸牌游戏实现
android·java·python·flutter·游戏
国强_dev1 天前
量体裁衣在技术方案中的应用
设计模式·系统架构
打工的小王1 天前
java并发编程(三)CAS
java·开发语言
飞Link1 天前
【Django】Django的静态文件相关配置与操作
后端·python·django
尤老师FPGA1 天前
使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第四十五讲)
android·java·ui