1 解决的问题

举个例子,有 100 个租客和 100 个房东。如果没有中介,租客要联系所有房东询问房子的情况,那么需要 100 * 100 个联系。如果有中介,房东将房子的情况告诉中介,租客只需要询问中介,就可以了解房子问题,只需要 200 个联系。有了中介后,需要的联系变少了。

2 中介模式

定义一个单独对象 (中介) 来封装一组对象间的交互,将这组对象间的交互委派给中介对象,来避免对象间的直接交互。

3 实现代码


** 抽象组件类 ** → 定义组件需要执行的方法操作;

public abstract class People {
    protected String name;
    protected Mediator mediator;    // 每个人都知道中介
 
    public People(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
 
    // 要执行的方法操作
    abstract void sendMessage(String msg);
    abstract void receiveMessage(String msg);
}

** 抽象中介类 ** → 定义中介要执行的方法操作,

public interface Mediator {
    void contact(People from, String msg);
}

** 具体组件类 ** → 继承抽象组件类,实现相关方法,不了解其他组件的状况,但都认识中介对象:

// 房东
public class Landlord extends People {
    private String demand;
    public Landlord(String name, Mediator mediator, String demand) {
        super(name, mediator);
        this.demand = demand;
    }
    public String getDemand() { return demand; }
    @Override void sendMessage(String msg) {
        System.out.println("【房东】" + name + "给中介发送消息: " + msg);
        mediator.contact(this, msg);
    }
    @Override void receiveMessage(String msg) {
        System.out.println("【房东】" + name + "收到消息: " + msg);
    }
}
 
// 租客
public class Tenant extends People {
    public Tenant(String name, Mediator mediator) {
        super(name, mediator);
    }
    @Override void sendMessage(String msg) {
        System.out.println("【租客】" + name + "给中介发送消息: " + msg);
        mediator.contact(this,msg);
    }
    @Override void receiveMessage(String msg) {
        System.out.println("【租客】" + name + "收到消息: " + msg);
    }
}

** 具体中介类 ** → 实现相关方法,需要知道所有具体组件,并从具体组件接收消息,并向具体组件发送消息。

public class HouseMediator implements Mediator {
    // 中介知道所有组件
    private final Map<String, Landlord> landlords = new HashMap<>();
    private final Map<String, Tenant> tenants = new HashMap<>();
    public void putLandlord(Landlord landlord) { landlords.put(landlord.name, landlord); }
    public void putTenant(Tenant tenant) { tenants.put(tenant.name, tenant); }
 
    @Override
    public void contact(People from, String msg) {
        if(from instanceof Landlord) {
            for (Tenant tenant: tenants.values()) {
                tenant.receiveMessage("有房东发布了新房源:" + ((Landlord)from).getDemand());
            }
        } else {
            for(Landlord landlord: landlords.values()) {
                if (msg.contains(landlord.getDemand())) {
                    System.out.println("租客" + from.name + "对" + landlord.getDemand() + "的房源感兴趣,通知下房东~");
                    landlord.receiveMessage("有人对您发布的房源感兴趣~");
                }
            }
        }
    }
}

4 优缺点

优点

  • 单一职责原则。将对象之间的关系抽取到同一个位置中。
  • 开闭原则。无需修改实际组件就能增加新的中介者。
  • 减轻应用中多个组件的耦合。
  • 更方便的复用各个组件。

缺点

  • 过度集中化,中介类要处理的内容太多,变成超级类,维护成本高;
  • 中介对象需要知道所有对象的交互逻辑,增加了学习成本;

5 应用场景

  • 当一些对象与其他对象之间紧密耦合时使用。将对象之间的所有关系抽取成一个类。
  • 解决对象之间的直接耦合问题。

6 经典应用例子

MVC 架构中,控制器就是中介者的体现。

下面是核心 Java 程序库中该模式的一些示例: