在设计代码结构的时候,我们经常会遇到这样的情况,按照需求我们有多个类要实现,而这多个类之间互相存在着业务关系。如果我们不假思索地直接把这些类实现的话,那么不但代码逻辑显得很混乱,而且耦合性很高,牵一发而动全身,很可能一处的代码需要修改就导致各个类中的代码都需要修改,这种“连坐”是我们需要尽力避免,中介者模式就是用来解决这类问题的。
中介者模式的定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。下面先盗个图:
抽象中介者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); } }
这样就把方法都交给中介者去调度了,而各个同事类只需要通知中介者去执行对应方法就可以了,类似于星型结构,高内聚低耦合。当需求改动时,在中介者实现类中修改对应方法就可以,符合迪米特原则。