zoukankan      html  css  js  c++  java
  • 中介者模式

    中介者模式

    1.概述

      中介者模式的本质在于”封装交互“。

      用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式的相互引用,从而降低耦合;而且可以独立地改变它们之间的交互。

    2.优缺点

    优点
      1)中介者类将对象的交互行为集中在一起,减少子类生成。

      2)将各要交互的对象解耦。
      3)对象与对象的交互(多对多关系)转换成中介者与对象的交互(一对多关系),更易于理解、维护和扩展。
      4)使注意力从对象各自本身的行为转移到它们之间的交互上来。有助于弄清楚一个系统中的对象是如何交互的。
      5)它使控制集中化,中介者模式将交互的复杂性变为中介者的复杂性。

    缺点

      1)“中介“承担了较多的责任,它可能变得比任一个Colleague都复杂。且一旦这个中介对象出现了问题,那么整个系统就会受到重大的影响。

      2)新增加一个同事类时,不得不去修改抽象中介者类和具体中介者类,此时可以使用观察者模式和状态模式来解决这个问题。

    3.何时选用中介者模式

      1)一组对象之间的通信方式比较复杂,导致相互依赖,结构混乱,可以采用中介者模式

      2)一个对象引用很多对象,并且跟这些对象交互,导致难以复用该对象

      但是不是所有系统都需要使用中介者模式把多对多的关系转化为多对一对多的。若各同事之间本来的关联就很清晰(没有交错关联),或这种关联并不复杂,没有必要应用中介者。

    4.比较

      在结构上,中介者模式与观察者模式、命令模式都添加了中间对象——只是中介者去掉了后两者在行为上的方向。但是观察者模式、命令模式中的观察者、命令都是被客户所知的,具体哪个观察者、命令的应用都是由客户来指定的;而大多中介者角色对于客户程序却是透明的。当然造成这种区别的原因是由于它们要达到的目的不同。 

    5.代码

      《大话设计模式C++版》

     1 #include "stdafx.h"
     2 #include <iostream>
     3 #include <string>
     4 #include <vector>
     5 using namespace std;
     6 
     7 class Colleague;
     8 //中介者类
     9 class Mediator
    10 {
    11 public:
    12   virtual void Send(string message,Colleague* col) = 0;
    13 };
    14 //抽象同事类
    15 class Colleague
    16 {
    17 protected:
    18   Mediator* mediator;
    19 public:
    20   Colleague(Mediator* temp)
    21   {
    22     mediator = temp;
    23   }
    24 };
    25 //同事一
    26 class Colleague1 : public Colleague
    27 {
    28 public:
    29   Colleague1(Mediator* media) : Colleague(media){}
    30 
    31   void Send(string strMessage)
    32   {
    33     mediator->Send(strMessage,this);
    34   }
    35   void Notify(string strMessage)
    36   {
    37     cout<<"同事一获得了消息"<<strMessage<<endl;
    38   }
    39 };
    40 
    41 //同事二
    42 class Colleague2 : public Colleague
    43 {
    44 public:
    45   Colleague2(Mediator* media) : Colleague(media){}
    46 
    47   void Send(string strMessage)
    48   {
    49     mediator->Send(strMessage,this);
    50   }
    51 
    52   void Notify(string strMessage)
    53   {
    54     cout<<"同事二获得了消息"<<strMessage<<endl;
    55   }
    56 };
    57 
    58 //具体中介者类
    59 class ConcreteMediator : public Mediator
    60 {
    61 public:
    62   Colleague1 * col1;
    63   Colleague2 * col2;
    64   virtual void Send(string message,Colleague* col)
    65   {
    66     if(col == col1)
    67       col2->Notify(message);
    68     else 
    69       col1->Notify(message);
    70   }
    71 };
    72 
    73 //客户端:
    74 int main()
    75 {
    76   ConcreteMediator * m = new ConcreteMediator();
    77 
    78   //让同事认识中介
    79   Colleague1* col1 = new Colleague1(m);
    80   Colleague2* col2 = new Colleague2(m);
    81 
    82   //让中介认识具体的同事类
    83   m->col1 = col1;
    84   m->col2 = col2;
    85 
    86   col1->Send("吃饭了吗?");
    87   col2->Send("还没吃,你请吗?");
    88 
    89   system("pause");
    90   return 0;
    91 }

      推荐一个比较好的例子

      http://blog.csdn.net/wuzhekai1985/article/details/6673603

     1 #include "stdafx.h"
     2 #include <iostream>
     3 #include <string>
     4 #include <vector>
     5 using namespace std;
     6 
     7 class Mediator;
     8 //抽象人
     9 class Person
    10 {
    11 protected:
    12   Mediator *m_mediator; //中介
    13 public:
    14   virtual void SetMediator(Mediator *mediator){} //设置中介
    15   virtual void SendMessage(string message) {}    //向中介发送信息
    16   virtual void GetMessage(string message) {}     //从中介获取信息
    17 };
    18 //抽象中介机构
    19 class Mediator
    20 {
    21 public:
    22   virtual void Send(string message, Person *person) {}
    23   virtual void SetA(Person *A) {}  //设置其中一方
    24   virtual void SetB(Person *B) {}
    25 };
    26 //租房者
    27 class Renter: public Person
    28 {
    29 public:
    30   void SetMediator(Mediator *mediator) { m_mediator = mediator; }
    31   void SendMessage(string message) { m_mediator->Send(message, this); }
    32   void GetMessage(string message) { cout<<"租房者收到信息"<<message; }
    33 };
    34 //房东
    35 class Landlord: public Person
    36 {
    37 public:
    38   void SetMediator(Mediator *mediator) { m_mediator = mediator; }
    39   void SendMessage(string message) { m_mediator->Send(message, this); }
    40   void GetMessage(string message) { cout<<"房东收到信息:"<<message; }
    41 };
    42 //房屋中介
    43 class HouseMediator : public Mediator
    44 {
    45 private:
    46   Person *m_A; //租房者
    47   Person *m_B; //房东
    48 public:
    49   HouseMediator(): m_A(0), m_B(0) {}
    50   void SetA(Person *A) { m_A = A; }
    51   void SetB(Person *B) { m_B = B; }
    52   void Send(string message, Person *person) 
    53   {
    54     if(person == m_A) //租房者给房东发信息
    55       m_B->GetMessage(message); //房东收到信息
    56     else
    57       m_A->GetMessage(message);
    58   }
    59 };
    60 //测试案例
    61 int main()
    62 {    
    63   Mediator *mediator = new HouseMediator();
    64   Person *person1 = new Renter();    //租房者
    65   Person *person2 = new Landlord();  //房东
    66   mediator->SetA(person1);
    67   mediator->SetB(person2);
    68   person1->SetMediator(mediator);
    69   person2->SetMediator(mediator);
    70   person1->SendMessage("我想在南京路附近租套房子,价格800元一个月
    ");
    71   person2->SendMessage("出租房子:南京路100号,70平米,1000元一个月
    ");
    72 
    73   delete person1; 
    74   delete person2; 
    75   delete mediator;
    76 
    77   system("pause");
    78   return 0;
    79 }

  • 相关阅读:
    POI 给单元格添加批注
    Linux下Mysql的odbc配置(修改网上博文)
    Linux下mysql实现类似于Sqlser的Profiler的访问记录监听功能
    windows下部署icescrum
    sql server2008查询会话的Ip地址、用户登录名、登录机器名
    error while loading shared libraries的解決方法
    做个标记,指针的指针的应用
    微信架构(转)
    网络监控netstat(转)
    大话MVC模式
  • 原文地址:https://www.cnblogs.com/SnailProgramer/p/4281095.html
Copyright © 2011-2022 走看看