设计模式——中介者模式

257 阅读4分钟

一、概述

中介者模式(Mediator Pattern),定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。中介者模式属于行为型模式。其主要的目的是用来降低多个对象和类之间通信的复杂性。

中介者模式就是提供一个平台,就比如房产中介提供房屋买卖的平台,卖家把房子挂到中介卖,买家就可以到中介去买,卖家和买家都是通过中介进行交互的,它们之间并不需要相关引用,这样就使得买家和卖家解耦。

中介者模式主要由这四个角色组成:

  • 抽象中介者(Mediator):作为一个抽象类或接口,用于与各协作对象之间进行通信。
  • ConcreteMediator(具体中介者):实现了抽象中介者的方法,实现了具体的逻辑。
  • Colleague(抽象协作者/同事):抽象出协作者的共有方法,同时他维持了一个对抽象中介者类的引用,其子类可以通过该引用进行通讯。
  • 具体协作者/同事(ConcreteColleague):实现了Colleague中的方法,每一个协作对象在需要和其他协作对象通信时先与中介者通信。

下面,我们就以房屋挂到中介买卖的例子说明。

二、使用

首先是抽象的中介者,它只有一个方法,就是卖房。

/**
 * 抽象中介者
 */
public interface Mediator {
    //卖房
    void sale(Seller agent, int area, int price);
}

然后是抽象的协作者/同事,类名我们以Seller卖家表示,这样好理解一些,里面持有了中介者的引用。

/**
 * 抽象的协作者-卖家
 */
public abstract class Seller {

    protected static final String TAG = "XXX";

    protected String name;
    protected Mediator mediator;

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

    public void sellHouse(int area, int price){
        mediator.sale(this, area, price);
    }

    //展示优点
    public abstract void showAdvantage();

}

再者就是具体的同事类,这里我们定义了三个卖房的同事类,并在showAdvantage()这个抽象方法中实现了自己的逻辑,展示了这个房子的优点。

/**
 * 具体的协作者(同事)——张三
 */
public class ZhangSan extends Seller {

    public ZhangSan(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    public void showAdvantage() {
        Log.e(TAG, "我的房子是学区房哦~~~");
    }
}
/**
 * 具体的协作者(同事)——李四
 */
public class LiSi extends Seller {

    public LiSi(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    public void showAdvantage() {
        Log.e(TAG, "我的房子靠近地铁口哦~~~");
    }
}
/**
 * 具体的协作者(同事)——王五
 */
public class WangWu extends Seller {

    public WangWu(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    public void showAdvantage() {
        Log.e(TAG, "我的房子有商超、医院等周边配套哦~~~");
    }
}

最后就是具体的中介者,可以看到,持有了所有的卖家,它们都是通过中介通信的,而卖家之间不会有直接的通信,并在sale这个抽象方法中,实现了具体的买卖逻辑。

/**
 * 具体的中介者
 */
public class ConcreteMediator implements Mediator {
    private static final String TAG = "XXX";

    private ZhangSan zhangSan;
    private LiSi liSi;
    private WangWu wangWu;

    public void setZhangSan(ZhangSan zhangSan) {
        this.zhangSan = zhangSan;
    }

    public void setLiSi(LiSi liSi) {
        this.liSi = liSi;
    }

    public void setWangWu(WangWu wangWu) {
        this.wangWu = wangWu;
    }

    @Override
    public void sale(Seller agent, int area, int price) {
        Log.e(TAG, "我是:" + agent.name + ",房屋面积:" + area + "平,报价:" + price + "万");
        if(agent == zhangSan){
            zhangSan.showAdvantage();
        }else if(agent == liSi){
            liSi.showAdvantage();
        }else{
            wangWu.showAdvantage();
        }
    }
}

最后,进行测试。首先创建了具体的中介者对象,以及3个卖家对象,并把卖家对象设置到中介。打印输出如下图所示。

ConcreteMediator concreteHouse = new ConcreteMediator();
ZhangSan zhangSan = new ZhangSan("张三",concreteHouse);
LiSi liSi = new LiSi("李四",concreteHouse);
WangWu wangWu = new WangWu("王五",concreteHouse);

concreteHouse.setZhangSan(zhangSan);
concreteHouse.setLiSi(liSi);
concreteHouse.setWangWu(wangWu);

zhangSan.sellHouse(121,188);
Log.e(TAG, "----------------------------");
liSi.sellHouse(89,249);
Log.e(TAG, "----------------------------");
wangWu.sellHouse(61,101);

三、总结

使用中介者模式有以下优点:

  • 中介中模式简化了对象之间的交互,它用中介者和同事的一对多交互替代了原来同事类之间的多对多的交互,一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构换成相对接单的星状结构;
  • 可将各个同事类对象进行解耦,可以独立地改变和复用各个同事类和中介者;

当然也会有一些不足就是,如果代码中存在过多的同事类时,就会导致中介类非常复杂,使得系统难以维护。

github地址:github.com/leewell5717…

四、参考

Java进阶篇设计模式之十 ---- 访问者模式和中介者模式

Android 中介者模式