中介者模式的定义为: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 it lets you vary their interaction independently.(用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。)
从类图中看,中介者模式由以下几部分组成:
Mediator 抽象中介者角色 抽象中介者角色定义统一的接口,用于各同事角色之间的通信。
Concrete Mediator 具体中介者角色 具体中介者角色通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
Colleague 同事角色 每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中 介者角色协作。每个同事类的行为分为两种:一种是同事本身的行为,比如改变对象本身的 状态,处理自己的行为等,这种行为叫做自发行为(Self-Method),与其他的同事类或中介 者没有任何的依赖;第二种是必须依赖中介者才能完成的行为,叫做依赖方法(DepMethod)。
这里用一个具体的例子来做说明,一群人参加一场赌博游戏:
每个人初始都有100积分 每局赌注都是一定数量的积分 每局只会有一位赢家 输家会从积分里扣除赌注相同的数值 赢家则会赢得其他所有人输掉的积分之和 如果是我参加上面这个游戏,我肯定只会盯着自己的积分(钱包),不想别的玩家直接对我的钱包动手动脚,我也没权利去对别人的钱包动手动脚。而且我更不想在每局结算的时候,去算自己应该加多少分,谁谁谁应该扣多少分,我是来享受游戏的。
这时候就该荷官(中介者)出场了,这样每局关于其他玩家结算的事情都交给他全权处理,我只用管好我自己的积分就行。
以下是中介者的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public abstract class Mediator { protected ConcreteColleague1 c1; protected ConcreteColleague2 c2; protected ConcreteColleague3 c3; public void setC1 (ConcreteColleague1 c1) { this .c1 = c1; } public void setC2 (ConcreteColleague2 c2) { this .c2 = c2; } public void setC3 (ConcreteColleague3 c3) { this .c3 = c3; } public abstract int lostExceptC1 (int num) ; public abstract int lostExceptC2 (int num) ; public abstract int lostExceptC3 (int num) ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ConcreteMediator extends Mediator { @Override public int lostExceptC1 (int num) { super .c2.decrease(num); super .c3.decrease(num); return num + num; } @Override public int lostExceptC2 (int num) { super .c1.decrease(num); super .c3.decrease(num); return num + num; } @Override public int lostExceptC3 (int num) { super .c1.decrease(num); super .c2.decrease(num); return num + num; } }
不难看出这位荷官,支持3个人进行游戏,每局都会从输家那里扣除积分,并计算出总分来。
下面是同事类及其具体实现类:
1 2 3 4 5 6 7 public abstract class Colleague { protected Mediator mediator; public Colleague (Mediator mediator) { this .mediator = mediator; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class ConcreteColleague1 extends Colleague { private int money = 100 ; public ConcreteColleague1 (Mediator mediator) { super (mediator); } public void increase (int num) { this .money += num; System.out.println("colleague1's money is: " + money); } public void decrease (int num) { this .money -= num; System.out.println("colleague1's money is: " + money); } public void win (int num) { int total = super .mediator.lostExceptC1(num); this .increase(total); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class ConcreteColleague2 extends Colleague { private int money = 100 ; public ConcreteColleague2 (Mediator mediator) { super (mediator); } public void increase (int num) { this .money += num; System.out.println("colleague2's money is: " + money); } public void decrease (int num) { this .money -= num; System.out.println("colleague2's money is: " + money); } public void win (int num) { int total = super .mediator.lostExceptC2(num); this .increase(total); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class ConcreteColleague3 extends Colleague { private int money = 100 ; public ConcreteColleague3 (Mediator mediator) { super (mediator); } public void increase (int num) { this .money += num; System.out.println("colleague3's money is: " + money); } public void decrease (int num) { this .money -= num; System.out.println("colleague3's money is: " + money); } public void win (int num) { int total = super .mediator.lostExceptC3(num); this .increase(total); } }
以上3位玩家都能很好的对自己积分进行增减计算,但是涉及到多人同场竞技,就不得不依赖荷官(中介)来出手相助了。
最后看看整局游戏是如何进行的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class Client { public static void main (String[] args) { Mediator mediator = new ConcreteMediator(); ConcreteColleague1 c1 = new ConcreteColleague1(mediator); ConcreteColleague2 c2 = new ConcreteColleague2(mediator); ConcreteColleague3 c3 = new ConcreteColleague3(mediator); mediator.setC1(c1); mediator.setC2(c2); mediator.setC3(c3); System.out.println("---- round 1 ----" ); c3.win(20 ); System.out.println("---- round 2 ----" ); c1.win(50 ); } }
结果:
1 2 3 4 5 6 7 8 9 ---- round 1 ---- colleague1's money is: 80 colleague2' s money is: 80 colleague3's money is: 140 ---- round 2 ---- colleague2' s money is: 30 colleague3's money is: 90 colleague1' s money is: 180
优点 中介者模式的优点就是减少类间的依赖,把原有的一对多的依赖变成了一对一的依赖, 同事类只依赖中介者,减少了依赖,当然同时也降低了类间的耦合。
缺点 中介者模式的缺点就是中介者会膨胀得很大,而且逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就越复杂。
使用场景 中介者模式适用于多个对象之间紧密耦合的情况,紧密耦合的标准是:在类图中出现了蜘蛛网状结构。在这种情况下一定要考虑使用中介者模式,这有利于把蜘蛛网梳理为星型结构,使原本复杂混乱的关系变得清晰简单。
一些实际应用: