在设计代码结构的时候,我们经常会遇到这样的情况,按照需求我们有多个类要实现,而这多个类之间互相存在着业务关系。如果我们不假思索地直接把这些类实现的话,那么不但代码逻辑显得很混乱,而且耦合性很高,牵一发而动全身,很可能一处的代码需要修改就导致各个类中的代码都需要修改,这种“连坐”是我们需要尽力避免,中介者模式就是用来解决这类问题的。
中介者模式的定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。下面先盗个图:

抽象中介者Mediator:定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。
中介者实现类ConcreteMediator:从抽象中介者继承而来,实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。
抽象同事类Colleague:同时类的抽象,具有同事类的共同特征。
同事类ConcreteColleague:如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。
我们拿宝信MES的产供销一体化做个简化模型:现在有生产、库存和销售三个类,假如平时每次生产10个,当库存大于等于100个,就停止生产,销售的量达到库存的一半就要生产双倍,这样一来三个类互相有关联,事实上宝信的产供销一体化不仅有采购库存销售,还有生产、资材、运输、财务等等模块,这些模块互相都有关联,如果直接做的话,估计能麻烦死,为了说明中介者模式,还是用上面说的三个类。
static class Maker {
public Maker() {
}
public static void make() {
if(Stock.goods>=100){
return;
}
Stock.goods+=10;
System.out.println("生产了10件产品");
}
}
static class Stock {
public static int goods;
public Stock() {
}
public void clear(){
}
}
class Sale extends Colleague {
public Sale() {
}
public void sale(int i) {
if(i>=Stock.goods){
Maker.make();
Maker.make();
}
Stock.goods-=i
}
}
这样三个类相互纠缠,修改点需求就会比较麻烦,下面用中介者来调度
abstract class Mediator {
protected Maker maker;
protected Stock stock;
protected Sale sale;
public Mediator() {
maker = new Maker(this);
stock = new Stock(this);
sale = new Sale(this);
}
public abstract void excute(String str, Object...obj);
}
class ConcreteMediator extends Mediator {
@Override
public void excute(String str, Object... obj) {
if(str.equals("maker.make")) {
this.make();
}
if(str.equals("stock.clear")) {
this.clear();
}
if(str.equals("sale.sale")) {
this.sale((int)obj[0]);
}
}
private void sale(int i) {
if(i>=super.stock.goods){
this.make();
this.make();
}
super.stock.goods-=i;
}
private void clear() {
super.stock.goods = 0;
System.out.println("清仓");
}
private void make() {
if(super.stock.goods>=100){
return;
}
super.stock.goods+=10;
System.out.println("生产了10件产品");
}
}
abstract class AbstractColleague {
protected Mediator mediator;
public AbstractColleague(Mediator _mediator) {
this.mediator = _mediator;
}
}
class Maker extends AbstractColleague {
public Maker(Mediator _mediator) {
super(_mediator);
}
public void make() {
super.mediator.excute("maker.make");
}
}
class Stock extends AbstractColleague {
public int goods;
public Stock(Mediator _mediator) {
super(_mediator);
}
public void clear() {
super.mediator.excute("stock.clear");
}
}
class Sale extends AbstractColleague {
public Sale(Mediator _mediator) {
super(_mediator);
}
public void sale(int i) {
super.mediator.excute("sale.sale",i);
}
}
这样就把方法都交给中介者去调度了,而各个同事类只需要通知中介者去执行对应方法就可以了,类似于星型结构,高内聚低耦合。当需求改动时,在中介者实现类中修改对应方法就可以,符合迪米特原则。