設計模式之中介者模式(Mediator)


一、初識中介者模式

那些年,我們一起上過的大學,班級里有班長,有團書記。想一想如果沒有QQ這種通訊工具的話,那么班長或者團支書該怎樣下達消息呢??同時,班級上兩個同學之間也可惜溝通啊,溝通一下,院里哪個女生,哪個帥哥呀~~~如果沒有QQ的話,大概就是下面的情景:

哎呀呀,看看這個亂那。如果同學的數目多起來就會變成網狀的結構啦。原本把一個系統分割成一些對象是可以增強復用性的,但是現在的情況是,這些兌現之間存在着大量的聯系,耦合性極高。這是很不利於復用的,同時這種情況使得系統的靈活性大大的降低,使得對系統的擴展很難,要是新轉來一個學生的話,要改動的地方就多了去了。

如果現在可以使用QQ,那么可以采用另一種方式設計這個系統呢,比如做成星形的結構:

看看這種“星形結構”和“網狀結構”的區別吧,顯然采用星形結構就可以避免上面的網狀結構存在的問題了,實際上這里的QQ就是指的是中介,這樣一來每個學生對象就不用存在耦合了,同學之間需要交流可以通過一個QQ群。

本人認為,由原來的網狀結構到星形結構的轉變是理解中介者模式比較好的途徑,下面來具體看看中介者模式,GoF說:


中介者模式(Mediator Pattern):定義一個中介對象來封裝系列對象之間的交互。中介者使各個對象不需要顯示地相互引用,從而使其耦合性松散,而且可以獨立地改變他們之間的交互。


看看結構圖的形象描述吧:

對於設計模式這個東西,理解了,應該寫一個代碼體會一下:看看這些類,比如:Mediator,ConcreteMediator,Colleague和ConcreteColleage1到底是怎么組織的。

View Code
  1 #include <iostream>
  2 #include <vector>
  3 #include <string>
  4 
  5 using namespace std;
  6 
  7 
  8 //抽象的同事類
  9 class Colleage
 10 {
 11 private:
 12     string name;
 13     string content;
 14 public:
 15     Colleage(string n = " "):name(n){};
 16     void set_name(string name)
 17     {
 18         this->name = name;
 19     }
 20     string get_name()
 21     {
 22         return this->name;
 23     }
 24     void set_content(string content)
 25     {
 26         this->content = content;
 27     }
 28     string get_content()
 29     {
 30         return content;
 31     }
 32     virtual void talk(){};
 33 
 34 };
 35 //具體的同事類:班長
 36 class Monitor : public Colleage
 37 {
 38 public:
 39     Monitor(string n = ""):Colleage(n){};
 40     virtual void talk()
 41     {
 42         cout<<"大班長 說:"<<get_content()<<endl;
 43     }
 44 };
 45 //具體的同事類:團支書
 46 class TuanZhiShu : public Colleage
 47 {
 48 public:
 49     TuanZhiShu(string n = ""):Colleage(n){};
 50     virtual void talk()
 51     {
 52         cout<<"團支書 說:"<<get_content()<<endl;
 53     }
 54 };
 55 //具體的同事類:同學A
 56 class StudentA : public Colleage
 57 {
 58 public:
 59     StudentA(string n = ""):Colleage(n){};
 60     virtual void talk()
 61     {
 62         cout<<"學生 A 說:"<<get_content()<<endl;
 63     }
 64 };
 65 //具體的同事類:同學B
 66 class StudentB : public Colleage
 67 {
 68 public:
 69     StudentB(string n = ""):Colleage(n){};
 70     virtual void talk()
 71     {
 72         cout<<"學生 B 說:"<<get_content()<<endl;
 73     }
 74 };
 75 //抽象中介者
 76 class Mediator
 77 {
 78 public:
 79     vector<Colleage*> studentList;
 80     virtual void add_student(Colleage *student)
 81     {
 82         studentList.push_back(student);
 83     };
 84     virtual void notify(Colleage *student){};
 85     virtual void chart(Colleage *student1,Colleage *student2){};
 86 };
 87 //具體中介者qq通訊平台
 88 class QQMediator : public Mediator
 89 {
 90 public:
 91     virtual void notify(Colleage *student)
 92     {
 93         student->talk();
 94         for(int i = 0 ; i < studentList.size() ; ++i)
 95         {
 96             //不是說話者
 97             if(student != studentList[i])
 98             {
 99                 studentList[i]->talk();
100             }
101         }
102     };
103     virtual void chart(Colleage *student1,Colleage *student2)
104     {
105         student1->talk();
106         student2->talk();
107     }
108 };
109 
110 
111 int main()
112 {
113     QQMediator qq;
114     Monitor studentMonitor("Vincent");
115     TuanZhiShu studentTuanZhiShu("Robort");
116     StudentA studentA("Sam");
117     StudentB studentB("Tom");
118     /*----------------------班長發通知-----------------------------*/
119     cout<<"下面的班長發布一個通知的場景:"<<endl;
120     //將同學們加入到qq群中
121     qq.add_student(&studentMonitor);
122     qq.add_student(&studentTuanZhiShu);
123     qq.add_student(&studentA);
124     qq.add_student(&studentB);
125     //設置大家的回復信息
126     studentMonitor.set_content("明天下午2點開年級會,收到回復^^。");
127     studentTuanZhiShu.set_content("知道了,肯定到!!");
128     studentA.set_content("收到了,但是可能晚點到!!");
129     studentB.set_content("收到了,但是明天要去面試!!");
130     //開始發通知
131     qq.notify(&studentMonitor);
132     /*--------------------兩個同學私下交流--------------------------*/
133     cout<<endl<<"下面是兩個同學的私下交流:"<<endl;
134     studentMonitor.set_content("你覺得咱們“軟件項目管理老師”講的怎么樣?");
135     studentA.set_content("我覺得講的不夠生動,還點名,不太好!!!");
136     qq.chart(&studentMonitor,&studentA);
137     return 0;
138 }

下面是運行的結果:

看看,這樣就利用qq這個平台完成了同學之間的交流。並且同學之間並沒有相互聯系,聯系都是通過qq實現的,如果現在要對象進行擴展,比如也可以通過飛信啊,只需要加入class FeiXin:public Mediator 就可以了,如果想擴展同學C只需要,class StudentC:public Colleage 即可。並且在客戶端的使用也是很方便的哦~~這時回過頭想一想如果不用“中介者模式”的話,系統會是什么樣呢???

二、使用中介者模式的場合和優缺點

使用終結者模式的場合

1.一組定義良好的對象,現在要進行復雜的通信。

2.定制一個分布在多個類中的行為,而又不想生成太多的子類。

可以看出,中介對象主要是用來封裝行為的,行為的參與者就是那些對象,但是通過中介者,這些對象不用相互知道。呵呵~~~

使用中介者模式的優點:

1.降低了系統對象之間的耦合性,使得對象易於獨立的被復用。

2.提高系統的靈活性,使得系統易於擴展和維護。

使用中介者模式的缺點:

中介者模式的缺點是顯而易見的,因為這個“中介“承擔了較多的責任,所以一旦這個中介對象出現了問題,那么整個系統就會受到重大的影響。

  


學習中的一點總結,歡迎拍磚哦^^


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM