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 程序库中该模式的一些示例:
java.util.Timer(所有scheduleXXX()方法)java.util.concurrent.Executor#execute()java.util.concurrent.ExecutorService(invokeXXX()和submit()方法)java.util.concurrent.ScheduledExecutorService(所有scheduleXXX()方法)java.lang.reflect.Method#invoke()