定义 Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and iit lets you vary their interaction independently.(用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变他们之间的交互) 组成Mediator抽象中介者:抽象中介者定义统一的接口,用于各同事角色之间的通行 Concrete Mediator具体中介者角色:具体中介者角色通过协调各同时角色实现协作行为,必须依赖于各个同事角色 Colleague同事角色:每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。同事类行为分为两种:同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介者没有任何的依赖。 依赖方法,必须依赖中介者才能完成的行为。 优点 减少了类间依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖也降低了耦合 缺点 中介者会膨胀的很大,而且业务逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑越复杂。 使用场景 中介者模式虽然简单,但是会被误用。类间的依赖是必然的,如果只是简单的几个对象的依赖关系,为了使用设计模式而加入了中介者模式,会导致中介者的逻辑复杂化。
场景:类图中出现了蜘蛛网结构,使用中介者模式将其转换为星型结构 N个对象之间产生了相互依赖关系(N>2) 多个对象有依赖关系,但是依赖的行为不确定,或有改变的可能 产品开发(如MVC框架),非项目开发 代码 通用类图
中介者模式 类图
代码 抽象中介者(抽象类 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package com.pattern.mediator;public abstract class Mediator { protected Colleague1 colleague1; protected Colleague2 colleague2; public Colleague1 getColleague1 () { return colleague1; } public Colleague2 getColleague2 () { return colleague2; } public void setColleague1 (Colleague1 colleague1) { this .colleague1 = colleague1; } public void setColleague2 (Colleague2 colleague2) { this .colleague2 = colleague2; } public abstract void doSometing1 () ; public abstract void doSomething2 () ; }
具体中介者(继承自抽象类 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.pattern.mediator;public class ConcreteMediator extends Mediator { @Override public void doSometing1 () { super .colleague1.selfMethod1(); super .colleague2.selfMethod2(); } @Override public void doSomething2 () { super .colleague2.selfMethod2(); super .colleague1.selfMethod1(); } }
同事类抽象(抽象类 )「需要产生依赖的类」
1 2 3 4 5 6 7 8 9 10 package com.pattern.mediator;public abstract class Colleague { protected Mediator mediator; public Colleague (Mediator mediator) { this .mediator = mediator; } }
具体同事类1(继承自抽象类 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package com.pattern.mediator;public class Colleague1 extends Colleague { public Colleague1 (Mediator mediator) { super (mediator); } public void selfMethod1 () { System.out.println("同事1自己的自有业务逻辑" ); } public void depMethod1 () { System.out.println("同事1通过中介者调用的业务逻辑" ); super .mediator.doSometing1(); } }
具体同事类2(继承自抽象类 )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.pattern.mediator;public class Colleague2 extends Colleague { public Colleague2 (Mediator mediator) { super (mediator); } public void selfMethod2 () { System.out.println("同事2自己的自有业务逻辑" ); } public void depMethod2 () { System.out.println("同事2通过中介者调用的业务逻辑" ); } }
测试代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package com.pattern;import com.pattern.mediator.*;import org.junit.Test;public class MediatorTest { @Test public void Test () { System.out.println("--------创建一个中介者--------" ); Mediator mediator = new ConcreteMediator (); System.out.println("--------创建一个同事类--------" ); Colleague1 colleague1 = new Colleague1 (mediator); Colleague2 colleague2 = new Colleague2 (mediator); mediator.setColleague1(colleague1); mediator.setColleague2(colleague2); System.out.println("--------同事类调用自己的方法--------" ); colleague1.selfMethod1(); System.out.println("--------同事类调用依赖的方法(通过中介者与其他类产生依赖的方法)--------" ); colleague1.depMethod1(); } }
结果
注意 在中介者模式(中介者中)中很少用到接口或抽象类,因为这些类是协作关系,完成不同的任务,处理不同的业务。 中介者中的方法,复杂业务的实现是依赖同事类来完成的 同事类最好使用构造函数注入中介者,中介者使用getter/setter注入同事类;因为同事类必须有中介者,而中介者可以只有部分同事类 不要刻意追求使用中介者模式