定义

行为型模式,集中相关对象之间复杂的沟通和控制方式。使用一个中介对象来封装一系列的对象交互。中介者使得各个对象之前不需要显示的相互引用,使各个对象之前松耦合,可以独立改变各对象的交互。

类图

类图中涉及的角色:

  • Mediator:抽象中介者,定义同事类到中介类的行为
  • Colleague:抽象同事类
  • ConcreteMediator:具体的中介类,实现抽象中介者中的方法,集合的方式管理所有同事类,接收某个同事对象的消息,完成相应操作
  • ConcreteColleague:具体的同事类,所有的具体同事类之间不显示的做交互,而是依赖具体中介者做行为交互
  • Client:客户端

中介者模式的实现

Colleague

/**
 * 抽象同事类
 */
public abstract class Colleague {

    private Mediator mediator;
    public String name;

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

    public Mediator getMediator() {
        return mediator;
    }

    public abstract void sendMessage(int stateChange);
}

ConcreteColleague

/**
 * 具体同事类
 */
public class ConcreteColleague1 extends Colleague{

    public ConcreteColleague1(Mediator mediator, String name) {
        super(mediator, name);
        // 在创建具体同事对象时,将自己放入ConcreteMediator对象集合中
        mediator.register(name, this);
    }

    @Override
    public void sendMessage(int stateChange) {
        // 调用中介者对象的getMessage
        this.getMediator().getMessage(stateChange, this.name);
    }

    public void doing1(){
        // 发消息给同事2
        sendMessage(0);
        System.out.println("ConcreteColleague1 doing.......");
    }
}
/**
 * 具体同事类
 */
public class ConcreteColleague2 extends Colleague{

    public ConcreteColleague2(Mediator mediator, String name) {
        super(mediator, name);
        // 在创建具体同事对象时,将自己放入ConcreteMediator对象集合中
        mediator.register(name, this);
    }

    @Override
    public void sendMessage(int stateChange) {
        // 调用中介者对象的getMessage
        this.getMediator().getMessage(stateChange, this.name);
    }

    public void doing2(){
        System.out.println("ConcreteColleague2 doing.......");
    }
}

Mediator

/**
 * 抽象中介者
 */
public abstract class Mediator {

    /**
     * 将具体同事类对象加入集合中
     */
    public abstract void register(String colleagueName, Colleague colleague);

    /**
     * 接收具体同事类对象发出的消息
     */
    public abstract void getMessage(int stateChange, String colleagueName);
}

ConcreteMediator

/**
 * 具体的中介者
 */
public class ConcreteMediator extends Mediator{

    // 存放所有的同事对象
    private HashMap<String , Colleague> colleagueHashMap;
    private HashMap<String ,String> interMap;

    public ConcreteMediator() {
        this.colleagueHashMap = new HashMap<>();
        this.interMap = new HashMap<>();
    }

    @Override
    public void register(String colleagueName, Colleague colleague) {
        colleagueHashMap.put(colleagueName, colleague);
        if(colleague instanceof ConcreteColleague1){
            interMap.put("concreteColleague1", colleagueName);
        }else if(colleague instanceof ConcreteColleague2){
            interMap.put("concreteColleague2", colleagueName);
        }
    }

    // 中介者核心方法(根据得到的消息完成对应的任务,中介者在这个方法中协调各个具体的同事对象,完成任务)
    @Override
    public void getMessage(int stateChange, String colleagueName) {
        if(colleagueHashMap.get(colleagueName) instanceof ConcreteColleague1){
            // 如果是ConcreteColleague1发送消息,且传入的状态是0,调用ConcreteColleague2的doing方法,否者不做任何事
            if(stateChange == 0){
                ((ConcreteColleague2)colleagueHashMap.get(interMap.get("concreteColleague2"))).doing2();
            }else{
                return;
            }
        }else if(colleagueHashMap.get(colleagueName) instanceof ConcreteColleague2){
            // 如果是ConcreteColleague2发送消息,调用ConcreteColleague1的doing方法
            ((ConcreteColleague1)colleagueHashMap.get(interMap.get("concreteColleague1"))).doing1();
        }
    }
}

Client

/**
 * 客户端
 */
public class Client {

    public static void main(String[] args) {
        // 创建一个中介者对象
        Mediator mediator = new ConcreteMediator();
        // 创建具体同事对象1加入中介者对象的集合中
        ConcreteColleague1 concreteColleague1 = new ConcreteColleague1(mediator, "concreteColleague1");
        // 创建具体同事对象2加入中介者对象的集合中
        ConcreteColleague2 concreteColleague2 = new ConcreteColleague2(mediator, "concreteColleague2");

        // 具体同事对象1发送消息
        concreteColleague1.sendMessage(0);
        concreteColleague1.sendMessage(1);
        System.out.println("===================================");
        // 具体同事对象2发送消息
        concreteColleague2.sendMessage(-1);
    }
}
ConcreteColleague2 doing.......
===================================
ConcreteColleague2 doing.......
ConcreteColleague1 doing.......

首先创建具体中介者对象,接着创建各个同事类对象,在创建同事类对象的时候直接通过构造器加入中介者的colleagues属性中。同事类对象可以通过sendMessage,最终会调用ConcreteMediator的getMessage方法,getMessage方法收到同事类对象的消息后,根据收到的消息来协调调用其他同事对象完成任务。核心处理逻辑在getMessage。

外观模式与中介者模式

外观模式与中介者模式类似,都是通过外部系统控制内部多个系统,但是外观模式下内部系统如果脱离外部系统还是可以独立运行的,而中介者模式的内部系统是需要中介者来协调运行的。在外观模式中,子系统可能不知道是由外部系统统一来访问他们的,但是中介者模式每个内部子系统是知道中介者的存在的。

中介者模式的优缺点

  • 优点:
    • 将对象彼此解耦,增加对象的复用性,符合迪米特法则
    • 集中控制逻辑,简化系统维护
    • 使对象之间传递消息变得简单
  • 缺点:
    • 设计不当将会导致中介者对象本身过于复杂
    • 中介者对象承担较多责任,对系统影响较大
  • 适用场景:
    • 适合于使用中间对象来封装其他子对象的交互,将子对象之间的依赖关系解耦
    • 想要封装多个类的行为又不想创建太多子类,可以使用中介者,当需要更改协调行为的逻辑时可以再新增新的中介者子类

参考

  • 《Head First 设计模式》
  • 谷粒学院
最后修改日期: 2019年11月16日

作者

留言

撰写回覆或留言

发布留言必须填写的电子邮件地址不会公开。