标签:
中介者模式:
那些年,我们一起上过的大学,班级里有班长,有团书记。想一想如果没有QQ这种通讯工具的话,那么班长或者团支书该怎样下达消息呢??同时,班级上两个同学之间也可惜沟通啊,沟通一下,院里哪个女生,哪个帅哥呀~~~如果没有QQ的话,大概就是下面的情景:
哎呀呀,看看这个乱那。如果同学的数目多起来就会变成网状的结构啦。原本把一个系 统分割成一些对象是可以增强复用性的,但是现在的情况是,这些兑现之间存在着大量的联系,耦合性极高。这是很不利于复用的,同时这种情况使得系统的灵活性 大大的降低,使得对系统的扩展很难,要是新转来一个学生的话,要改动的地方就多了去了。
如果现在可以使用QQ,那么可以采用另一种方式设计这个系统呢,比如做成星形的结构:
看看这种“星形结构”和“网状结构”的区别吧,显然采用星形结构就可以避免上面的网状结构存在的问题了,实际上这里的QQ就是指的是中介,这样一来每个学生对象就不用存在耦合了,同学之间需要交流可以通过一个QQ群。
本人认为,由原来的网状结构到星形结构的转变是理解中介者模式比较好的途径,下面来具体看看中介者模式,GoF说:
中介者模式(Mediator Pattern):定义一个中介对象来封装系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互。
看看结构图的形象描述吧:
对于设计模式这个东西,理解了,应该写一个代码体会一下:看看这些类,比如:Mediator,ConcreteMediator,Colleague和ConcreteColleage1到底是怎么组织的。
参与者:
Mediator: 抽象中介者。定义了同事对象到中介者对象之间的接口。
ConcreteMediator: 具体中介者。实现抽象中介者的方法,它需要知道所有的具体同事类,同时需要从具体的同事类那里接收信息,并且向具体的同事类发送信息。
Colleague: 抽象同事类。
ConcreteColleague: 具体同事类。每个具体同事类都只需要知道自己的行为即可,但是他们都需要认识中介者。
我们使用一个例子来说明一下什么是同事类:有两个类A和B,类中各有一个数字,并且要保证类B中的数字永远是类A中数字的100倍。也就是说,当修改类A 的数时,将这个数字乘以100赋给类B,而修改类B时,要将数除以100赋给类A。类A类B互相影响,就称为同事类。代码如下:
抽象的同事类:
1 abstract class AbstractColleague { 2 protected int number; 3 4 public int getNumber() { 5 return number; 6 } 7 8 public void setNumber(int number){ 9 this.number = number; 10 } 11 //注意这里的参数不再是同事类,而是一个中介者 12 public abstract void setNumber(int number, AbstractMediator am); 13 }
具体同事类A和B:
1 class ColleagueA extends AbstractColleague{ 2 public void setNumber(int number, AbstractColleague coll) { 3 this.number = number; 4 coll.setNumber(number*100); 5 } 6 }
1 class ColleagueB extends AbstractColleague{ 2 3 public void setNumber(int number, AbstractColleague coll) { 4 this.number = number; 5 coll.setNumber(number/100); 6 } 7 }
调用:
1 public class Client { 2 public static void main(String[] args){ 3 4 AbstractColleague collA = new ColleagueA(); 5 AbstractColleague collB = new ColleagueB(); 6 7 System.out.println("==========设置A影响B=========="); 8 collA.setNumber(1288, collB); 9 System.out.println("collA的number值:"+collA.getNumber()); 10 System.out.println("collB的number值:"+collB.getNumber()); 11 12 System.out.println("==========设置B影响A=========="); 13 collB.setNumber(87635, collA); 14 System.out.println("collB的number值:"+collB.getNumber()); 15 System.out.println("collA的number值:"+collA.getNumber()); 16 } 17 }
上面的代码中,类A类B通过直接的关联发生关系,假如我们要使用中介者模式,类A类B之间则不可以直接关联,他们之间必须要通过一个中介者来达到关联的目的。
同事类:
1 abstract class AbstractColleague { 2 protected int number; 3 4 public int getNumber() { 5 return number; 6 } 7 8 public void setNumber(int number){ 9 this.number = number; 10 } 11 //注意这里的参数不再是同事类,而是一个中介者 12 public abstract void setNumber(int number, AbstractMediator am); 13 } 14 class ColleagueA extends AbstractColleague{ 15 16 public void setNumber(int number, AbstractMediator am) { 17 this.number = number; 18 am.AaffectB(); 19 } 20 } 21 22 class ColleagueB extends AbstractColleague{ 23 24 @Override 25 public void setNumber(int number, AbstractMediator am) { 26 this.number = number; 27 am.BaffectA(); 28 } 29 }
抽象中介者类:
1 abstract class AbstractMediator { 2 protected AbstractColleague A; 3 protected AbstractColleague B; 4 5 public AbstractMediator(AbstractColleague a, AbstractColleague b) { 6 A = a; 7 B = b; 8 } 9 10 public abstract void AaffectB(); 11 12 public abstract void BaffectA(); 13 14 }
中介者类:
1 class Mediator extends AbstractMediator { 2 3 public Mediator(AbstractColleague a, AbstractColleague b) { 4 super(a, b); 5 } 6 7 //处理A对B的影响 8 public void AaffectB() { 9 int number = A.getNumber(); 10 B.setNumber(number*100); 11 } 12 13 //处理B对A的影响 14 public void BaffectA() { 15 int number = B.getNumber(); 16 A.setNumber(number/100); 17 } 18 }
客户端:
1 public class Client { 2 public static void main(String[] args){ 3 AbstractColleague collA = new ColleagueA(); 4 AbstractColleague collB = new ColleagueB(); 5 6 AbstractMediator am = new Mediator(collA, collB); 7 8 System.out.println("==========通过设置A影响B=========="); 9 collA.setNumber(1000, am); 10 System.out.println("collA的number值为:"+collA.getNumber()); 11 System.out.println("collB的number值为A的10倍:"+collB.getNumber()); 12 13 System.out.println("==========通过设置B影响A=========="); 14 collB.setNumber(1000, am); 15 System.out.println("collB的number值为:"+collB.getNumber()); 16 System.out.println("collA的number值为B的0.1倍:"+collA.getNumber()); 17 18 } 19 }
优点
适当地使用中介者模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。
使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。
使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
总结
在 面向对象编程中,一个类必然会与其他的类发生依赖关系,完全独立的类是没有意义的。一个类同时依赖多个类的情况也相当普遍,既然存在这样的情况,说明,一 对多的依赖关系有它的合理性,适当的使用中介者模式可以使原本凌乱的对象关系清晰,但是如果滥用,则可能会带来反的效果。一般来说,只有对于那种同事类之 间是网状结构的关系,才会考虑使用中介者模式。可以将网状结构变为星状结构,使同事类之间的关系变的清晰一些。
中介者模式是一种比较常用的模式,也是一种比较容易被滥用的模式。对于大多数的情况,同事类之间的关系不会复杂到混乱不堪的网状结构,因此,大多数情况下,将对象间的依赖关系封装的同事类内部就可以的,没有必要非引入中介者模式。滥用中介者模式,只会让事情变的更复杂。
标签:
原文地址:http://www.cnblogs.com/xfvipp/p/5486850.html