行为型设计模式——中介者模式

中介者模式

中介者模式主要是将关联关系由一个中介者类统一管理维护,一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下左图中,有六个同事类对象,假如对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。如果引入中介者模式,那么同事类之间的关系将变为星型结构,从下右图中可以看到,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。

定义: 又叫调停模式,定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式包含以下主要角色:

  • 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。

  • 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。

  • 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

  • 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

案例实现

【例】租房

现在租房基本都是通过房屋中介,房主将房屋托管给房屋中介,而租房者从房屋中介获取房屋信息。房屋中介充当租房者与房屋所有者之间的中介者。

类图如下:

代码如下:

首先租客和房东都是人,我们先定义Person抽象类,然后具体实现租客Tenant和房东HouseOwner类,代码如下:

java 复制代码
// 抽象类
public abstract class Person {
    protected String name;
    protected Mediator mediator; // 持有一个中介者对象
    public Person(String name,Mediator mediator){
        this.name = name;
        this.mediator = mediator;
    }
    public abstract String getMessage(String msg);
}

// 租客具体实现
public class Tenant extends Person{
    private String lease; // 租客租期
    public Tenant(String name,String lease, Mediator mediator) {
        super(name, mediator);
        this.lease = lease;
    }
    public String getMessage(String msg){
        System.out.println("我是租客,收到了中介发来的信息为:"+msg);
        return "我叫" + name +",我的想租"+lease;
    }
}

// 房东具体实现
public class HouseOwner extends Person{
    private String address; // 房东房子地址
    public HouseOwner(String name,String address, Mediator mediator) {
        super(name, mediator);
        this.address = address;
    }

    //获取信息
    public String getMessage(String msg){
        System.out.println("我是房东,收到中介发来的信息:"+msg);
        return "我叫" + name +",房子的位置是"+address;
    }
}

注意,上面的HouseOwnerTenant(都是同事类)都持有中介者对象,目的是让乱七八糟的同事类都和中介者类进行关联,而不是让同事类相互关联,后面进行调用只需要通过中介者类即可,下面定义中介者类:

java 复制代码
// 抽象中介类
public abstract class Mediator {
    private String name;
    public Mediator(String name){
        this.name = name;
    }
    public abstract String constact(String msg,Person person);
}

// 中介类具体实现
public class MediatorCompany extends Mediator{
    private HouseOwner houseOwner;
    private Tenant tenant;

    public MediatorCompany(String name) {
        super(name);
    }

    @Override
    public String constact(String msg,Person person) {
        if(person instanceof HouseOwner){
            // 如果是房东
            return houseOwner.getMessage(msg);
        }
        if(person instanceof Tenant){
            // 如果是租客
            return tenant.getMessage(msg);
        }
        return null;
    }

    public HouseOwner getHouseOwner() {
        return houseOwner;
    }

    public void setHouseOwner(HouseOwner houseOwner) {
        this.houseOwner = houseOwner;
    }

    public Tenant getTenant() {
        return tenant;
    }

    public void setTenant(Tenant tenant) {
        this.tenant = tenant;
    }
}

上面的代码只是维护了租客和房东两个同事类,如果还有其他的同事类例如开发商、政府、A公司、B公司等,那么constact的逻辑就比较复杂了。但是优点是将所有同事类都关联到一个中介者类中,减少了同事类之间的复杂关联关系。下面要实现房东和组合的通信或者调用,只需要通过中介者实现类即可,测试代码如下:

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 中介公司
        MediatorCompany mediatorCompany = new MediatorCompany("王牌中介公司");

        // 实例化同事类
        HouseOwner houseOwner = new HouseOwner("马云", "杭州西溪阿里园区",mediatorCompany);
        Tenant tenant = new Tenant("马化腾", "99年", mediatorCompany);

        mediatorCompany.setTenant(tenant);
        mediatorCompany.setHouseOwner(houseOwner);

        String msg1 = mediatorCompany.constact("你的房子什么情况呀?",houseOwner);
        System.out.println("房东回复:"+msg1);

        String msg2 = mediatorCompany.constact("你想租多久呀?",tenant);
        System.out.println("租客回复:"+msg2);
    }
}

结果输出:

我是房东,收到中介发来的信息:你的房子什么情况呀?

房东回复:我叫马云,房子的位置是杭州西溪阿里园区

我是租客,收到了中介发来的信息为:你想租多久呀?

租客回复:我叫马化腾,我的想租99年

优点

  • 松散耦合

    中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样"牵一处而动全身"了。

  • 集中控制交互

    多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事类不需要做修改。

  • 一对多关联转变为一对一的关联

    没有使用中介者模式的时候,同事对象之间的关系通常是一对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成双向的一对一,这会让对象的关系更容易理解和实现。

缺点

当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。

使用场景

  • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
  • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

参考内容:

传智播客设计模式相关笔记(主要)

相关推荐
MZ_ZXD001几秒前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
PP东3 分钟前
Flowable学习(二)——Flowable概念学习
java·后端·学习·flowable
ManThink Technology8 分钟前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
invicinble12 分钟前
springboot的核心实现机制原理
java·spring boot·后端
人道领域20 分钟前
SSM框架从入门到入土(AOP面向切面编程)
java·开发语言
大模型玩家七七41 分钟前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
CodeToGym1 小时前
【Java 办公自动化】Apache POI 入门:手把手教你实现 Excel 导入与导出
java·apache·excel
凡人叶枫1 小时前
C++中智能指针详解(Linux实战版)| 彻底解决内存泄漏,新手也能吃透
java·linux·c语言·开发语言·c++·嵌入式开发
JMchen1232 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
阔皮大师2 小时前
INote轻量文本编辑器
java·javascript·python·c#