问题
中介者模式和外观模式有些类似,学习中介者模式可以和外观模式对比着一起学习。可以参考设计模式之外观模式-与单一职责的PK(Facade)。下图是我总结的外观和中介者的区别。外观模式解决的是顾客频繁访问店内的各个部门的问题,增加接待经理,由接待经理来接待顾客,同时也由接待经理来与店内各个部门进行沟通处理。中介者解决的是店内各个部门频繁交互访问的问题,新增一个协调部门或者总经理担任中介者的角色,来协调各个部门频繁访问的问题。
废话不多说,我们来描述我的电脑城新的问题。我的电脑城现在有4个采购部,分别是A,B,C,D。A部门计划今天去某地采购电脑,就和B,C,D说我今天要去甲地采购电脑,你们就别过去了。B则说我也要去甲地采购,那我今天就不去了,C说我要去乙地采购,你们别去就行,D说我也要去乙地等等,就这样每天都在乱糟糟且冗长的讨论过程中,确定4个采购部每天的行程安排。我这一看,你们这效率不行啊,光同步讨论都要花费大量的时间。这就得我亲自出马了,你们给我把每天的计划提交给我,我给你们排上,你们按照我排的计划执行就行。这就是中介者模式的理念,其中我就是这个中介者。我们来撸代码吧。
实现
先看采购部的实现
public interface AbstractPurchase {
String getName();
void setMediator(Mediator mediator);
}
public class Purchase implements AbstractPurchase{
private String name;
private Mediator mediator;
public Purchase(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
@Override
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void addSchedule(String schedule) {
System.out.println(name + " add schedule: " + schedule);
mediator.addSchedule(name, schedule);
}
public void execute(String schedule) {
System.out.println(name + " " + schedule);
}
}
再看看我这个中介者的作用
public class Mediator {
private Purchase a;
private Purchase b;
private Purchase c;
private Purchase d;
private HashMap<String, List<String>> scheduleMap = new HashMap<>();
public Mediator(Purchase a, Purchase b, Purchase c, Purchase d) {
this.a = a;
this.b = b;
this.d = d;
this.c = c;
}
/**
* 纯手工调度
**/
public void schedule() {
System.out.println("after mediator schedule ");
for (String s : scheduleMap.keySet()) {
List<String> list = scheduleMap.get(s);
switch (s) {
case "A":
for (String temp : list) {
if (temp.contains("明天")) {
System.out.println("cancel A schedule :" + temp);
} else {
a.execute(temp);
}
}
break;
case "B":
System.out.println("change B schedule");
b.execute("明天去甲地采购配件");
break;
case "C":
c.execute(list.get(0));
break;
case "D":
System.out.println("cancel D schedule : " + list.get(0));
break;
default:
break;
}
}
}
public void addSchedule(String name, String schedule) {
List<String> schedules = scheduleMap.getOrDefault(name, new ArrayList<>());
schedules.add(schedule);
scheduleMap.put(name, schedules);
}
}
看下执行代码
public static void main(String[] args) {
Purchase purchaseA = new Purchase("A");
Purchase purchaseB = new Purchase("B");
Purchase purchaseC = new Purchase("C");
Purchase purchaseD = new Purchase("D");
Mediator mediator = new Mediator(purchaseA, purchaseB, purchaseC, purchaseD);
purchaseA.setMediator(mediator);
purchaseB.setMediator(mediator);
purchaseC.setMediator(mediator);
purchaseD.setMediator(mediator);
purchaseA.addSchedule("今天去甲地采购电脑");
purchaseA.addSchedule("明天去甲地采购配件");
purchaseB.addSchedule("今天去甲地采购配件");
purchaseC.addSchedule("今天去乙地采购电脑");
purchaseD.addSchedule("今天去乙地采购电脑");
mediator.schedule();
}
执行结果
A add schedule: 今天去甲地采购电脑
A add schedule: 明天去甲地采购配件
B add schedule: 今天去甲地采购配件
C add schedule: 今天去乙地采购电脑
D add schedule: 今天去乙地采购电脑
after mediator schedule
A 今天去甲地采购电脑
cancel A schedule :明天去甲地采购配件
change B schedule
B 明天去甲地采购配件
C 今天去乙地采购电脑
cancel D schedule : 今天去乙地采购电脑
总结
强迫症患者看到上面没有中介者到有中介者的过程,会很舒服,虽然增加了一个中介者,但减少了多个部门的繁杂无效率的沟通,这个在部门越多的时候体现的优越性也就更好。再举个更切合实际的例子就是机场的塔台,塔台是个非常典型的中介者的例子。在没有塔台之前,每架飞机想要在机场将落时,要广播给其他所有飞机,说我准备在几点几分哪个跑道降落,在其他飞机都同意了时,才可以降落。在机场几乎每天降落的飞机非常多,这个沟通效率就会非常的低,并且对机长的要求非常高,一不小心就会和其他飞机撞到一块。而有了塔台之后,机长只需要向塔台申请,说我希望何时落地,而塔台维护着所有的飞机降落申请,塔台安排好之后,告诉每架飞机何时降落即可。
中介者的优点:减少对象之间混乱无序的依赖关系。限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。
缺点:中介者会变成上帝对象。一旦中介者出错,会导致所有的依靠其交互的对象全部都会出错。