23种设计模式(7):中介者模式 [复制链接]

管理员 汇享云 实名认证 官方认证 2016-9-18 11:05:39 发表在 站长技术经验交流 查看全部 使用道具 举报 回复

原文出处:  卡奴达摩的专栏
定义:用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
类型:行为类模式
类图:
[/url]
中介者模式的结构
中介者模式又称为调停者模式,从类图中看,共分为3部分:

      
  • 抽象中介者:定义好同事类对象到中介者对象的接口,用于各个同事类之间的通信。一般包括一个或几个抽象的事件方法,并由子类去实现。  
  • 中介者实现类:从抽象中介者继承而来,实现抽象中介者中定义的事件方法。从一个同事类接收消息,然后通过消息影响其他同时类。  
  • 同事类:如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。
为什么要使用中介者模式
一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下图中,有六个同事类对象,假如对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个对象受到影响。也就是说,同事类之间直接关联的设计是不好的。
[url=http://www.importnew.com/?attachment_id=15551]
[/url]
如果引入中介者模式,那么同事类之间的关系将变为星型结构,从图中可以看到,任何一个类的变动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。
[url=http://www.importnew.com/?attachment_id=15552]

我们使用一个例子来说明一下什么是同事类:有两个类A和B,类中各有一个数字,并且要保证类B中的数字永远是类A中数字的100倍。也就是说,当修改类A的数时,将这个数字乘以100赋给类B,而修改类B时,要将数除以100赋给类A。类A类B互相影响,就称为同事类。代码如下:
  1. abstract class AbstractColleague {
  2.         protected int number;

  3.         public int getNumber() {
  4.                 return number;
  5.         }

  6.         public void setNumber(int number){
  7.                 this.number = number;
  8.         }
  9.         //抽象方法,修改数字时同时修改关联对象
  10.         public abstract void setNumber(int number, AbstractColleague coll);
  11. }

  12. class ColleagueA extends AbstractColleague{
  13.         public void setNumber(int number, AbstractColleague coll) {
  14.                 this.number = number;
  15.                 coll.setNumber(number*100);
  16.         }
  17. }

  18. class ColleagueB extends AbstractColleague{
  19.        
  20.         public void setNumber(int number, AbstractColleague coll) {
  21.                 this.number = number;
  22.                 coll.setNumber(number/100);
  23.         }
  24. }

  25. public class Client {
  26.         public static void main(String[] args){

  27.                 AbstractColleague collA = new ColleagueA();
  28.                 AbstractColleague collB = new ColleagueB();
  29.                
  30.                 System.out.println("==========设置A影响B==========");
  31.                 collA.setNumber(1288, collB);
  32.                 System.out.println("collA的number值:"+collA.getNumber());
  33.                 System.out.println("collB的number值:"+collB.getNumber());

  34.                 System.out.println("==========设置B影响A==========");
  35.                 collB.setNumber(87635, collA);
  36.                 System.out.println("collB的number值:"+collB.getNumber());
  37.                 System.out.println("collA的number值:"+collA.getNumber());
  38.         }
  39. }
复制代码
上面的代码中,类A类B通过直接的关联发生关系,假如我们要使用中介者模式,类A类B之间则不可以直接关联,他们之间必须要通过一个中介者来达到关联的目的。
  1. abstract class AbstractColleague {
  2.         protected int number;

  3.         public int getNumber() {
  4.                 return number;
  5.         }

  6.         public void setNumber(int number){
  7.                 this.number = number;
  8.         }
  9.         //注意这里的参数不再是同事类,而是一个中介者
  10.         public abstract void setNumber(int number, AbstractMediator am);
  11. }

  12. class ColleagueA extends AbstractColleague{

  13.         public void setNumber(int number, AbstractMediator am) {
  14.                 this.number = number;
  15.                 am.AaffectB();
  16.         }
  17. }

  18. class ColleagueB extends AbstractColleague{

  19.         @Override
  20.         public void setNumber(int number, AbstractMediator am) {
  21.                 this.number = number;
  22.                 am.BaffectA();
  23.         }
  24. }

  25. abstract class AbstractMediator {
  26.         protected AbstractColleague A;
  27.         protected AbstractColleague B;
  28.        
  29.         public AbstractMediator(AbstractColleague a, AbstractColleague b) {
  30.                 A = a;
  31.                 B = b;
  32.         }

  33.         public abstract void AaffectB();
  34.        
  35.         public abstract void BaffectA();

  36. }
  37. class Mediator extends AbstractMediator {

  38.         public Mediator(AbstractColleague a, AbstractColleague b) {
  39.                 super(a, b);
  40.         }

  41.         //处理A对B的影响
  42.         public void AaffectB() {
  43.                 int number = A.getNumber();
  44.                 B.setNumber(number*100);
  45.         }

  46.         //处理B对A的影响
  47.         public void BaffectA() {
  48.                 int number = B.getNumber();
  49.                 A.setNumber(number/100);
  50.         }
  51. }

  52. public class Client {
  53.         public static void main(String[] args){
  54.                 AbstractColleague collA = new ColleagueA();
  55.                 AbstractColleague collB = new ColleagueB();
  56.                
  57.                 AbstractMediator am = new Mediator(collA, collB);
  58.                
  59.                 System.out.println("==========通过设置A影响B==========");
  60.                 collA.setNumber(1000, am);
  61.                 System.out.println("collA的number值为:"+collA.getNumber());
  62.                 System.out.println("collB的number值为A的10倍:"+collB.getNumber());

  63.                 System.out.println("==========通过设置B影响A==========");
  64.                 collB.setNumber(1000, am);
  65.                 System.out.println("collB的number值为:"+collB.getNumber());
  66.                 System.out.println("collA的number值为B的0.1倍:"+collA.getNumber());
  67.                
  68.         }
  69. }
复制代码
虽然代码比较长,但是还是比较容易理解的,其实就是把原来处理对象关系的代码重新封装到一个中介类中,通过这个中介类来处理对象间的关系。
中介者模式的优点

      
  • 适当地使用中介者模式可以避免同事类之间的过度耦合,使得各同事类之间可以相对独立地使用。  
  • 使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。  
  • 使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
适用场景
在面向对象编程中,一个类必然会与其他的类发生依赖关系,完全独立的类是没有意义的。一个类同时依赖多个类的情况也相当普遍,既然存在这样的情况,说明,一对多的依赖关系有它的合理性,适当的使用中介者模式可以使原本凌乱的对象关系清晰,但是如果滥用,则可能会带来反的效果。一般来说,只有对于那种同事类之间是网状结构的关系,才会考虑使用中介者模式。可以将网状结构变为星状结构,使同事类之间的关系变的清晰一些。
中介者模式是一种比较常用的模式,也是一种比较容易被滥用的模式。对于大多数的情况,同事类之间的关系不会复杂到混乱不堪的网状结构,因此,大多数情况下,将对象间的依赖关系封装的同事类内部就可以的,没有必要非引入中介者模式。滥用中介者模式,只会让事情变的更复杂。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

全部评论/1021 条

只有登录之后才可以评论,请点击这里进行登录

隠姓埋茗 2016-9-24 10:10:35 沙发

有空一起交流一下 回复

Crazy゜ 2016-9-25 10:25:52 板凳

回个帖子,下班咯~ 回复

呆到深处自然萌 2016-9-25 11:06:45 地板

支持,楼下的跟上哈~ 回复

橘子味的猫 2016-9-25 16:44:33 5#

我也来顶一下.. 回复

Sadness。 2016-9-27 12:52:57 6#

路过 帮顶 嘿嘿 回复

咽泪装欢 2016-10-9 19:12:00 7#

众里寻他千百度,蓦然回首在这里! 回复

戒不掉的泪 2016-10-10 21:12:59 8#

在撸一遍。。。 回复

命中劫 2016-10-12 19:26:12 9#

支持,楼下的跟上哈~ 回复

Demon、微光 2016-10-14 20:12:45 10#

好困啊 回复

1关注

1粉丝

364帖子

发布作品
加入收藏 我要分享

分享到微信

打开微信扫一扫即可将网页分享至微信

分享到论坛或者博客

复制
作者的其他作品查看全部
快速回复 返回顶部 返回列表