设计模式之中介者模式20170731
行为型设计模式之中介者模式:
一、含义
用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
同事角色与其他同时角色通信的时候,一定要通过中介者角色(中介者封装了各个同事类之间的逻辑关系)
二、代码说明
1.主要有两个角色
1)中介者角色
通过协调各同事角色实现协作行为,因此它必须依赖于各个同事角色。
2)同事角色
每一个同事角色都知道中介者角色,而且与其他的同事角色通信的时候,一定要通过中介者角色协作。
每个同事类的行为分为两种:
一种是同事本身的行为,比如改变对象本身的状态,处理自己的行为等,这种方法叫做自发行为,与其他的同事类或中介者没有任何的依赖;
第二种是必须依赖中介者才能完成的行为,叫做依赖方法。
2.在用C实现过程中也是参考这种思想,以进销存管理举例,具体实现如下:
1)中介者模式使用场景:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : MediatorPatternUsage.c 5 * Description : 中介者模式的使用 6 7 book@book-desktop:/work/projects/test/DesignPatterns/MediatorPattern$ gcc -o MediatorPatternUsage Purchase.c Sale.c Stock.c MediatorPattern.c MediatorPatternUsage.c 8 book@book-desktop:/work/projects/test/DesignPatterns/MediatorPattern$ ./MediatorPatternUsage 9 ---------------采购人员采购电脑-------------- 10 IBM电脑的销售情况为:95 11 采购IBM电脑100台 12 库存数量为:200 13 ---------------销售人员销售电脑-------------- 14 IBM电脑的销售情况为:95 15 库存数量为:199 16 销售IBM电脑:1台 17 ---------------库房人员清库处理-------------- 18 清理存货数量为:199 19 折价销售IBM电脑199台 20 不再采购IBM电脑 21 22 * Created : 2017.07.28. 23 * Author : Yu Weifeng 24 * Function List : 25 * Last Modified : 26 * History : 27 ******************************************************************************/ 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 #include "MediatorPattern.h" 32 33 34 35 36 /***************************************************************************** 37 -Fuction : main 38 -Description : 39 -Input : 40 -Output : 41 -Return : 42 * Modify Date Version Author Modification 43 * ----------------------------------------------- 44 * 2017/07/28 V1.0.0 Yu Weifeng Created 45 ******************************************************************************/ 46 int main(int argc,char **argv) 47 { 48 T_Mediator tMediator=newMediator(&tMediator); 49 printf("---------------采购人员采购电脑--------------\r\n"); 50 T_Purchase tPurchase=newPurchase(&tMediator); 51 tPurchase.BuyIBMComputer(&tPurchase,100); 52 printf("---------------销售人员销售电脑--------------\r\n"); 53 T_Sale tSale=newSale(&tMediator); 54 tSale.SellIBMComputer(&tSale,1); 55 printf("---------------库房人员清库处理--------------\r\n"); 56 T_Stock tStock=newStock(&tMediator); 57 tStock.ClearStock(&tStock); 58 59 60 61 return 0; 62 }
2)被调用者:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : MediatorPattern.c 5 * Description : 中介者模式 6 本文件是中介者的具体实现 7 以进销存管理举例 8 9 * Created : 2017.07.28. 10 * Author : Yu Weifeng 11 * Function List : 12 * Last Modified : 13 * History : 14 ******************************************************************************/ 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include "MediatorPattern.h" 19 20 static void MediatorBuyComputer(T_Mediator *i_ptThis,int i_iNum); 21 static void MediatorSellComputer(T_Mediator *i_ptThis,int i_iNum); 22 static void MediatorOffSell(T_Mediator *i_ptThis); 23 static void MediatorClearStock(T_Mediator *i_ptThis); 24 25 26 /***************************************************************************** 27 -Fuction : MediatorExecute 28 -Description : 公有函数 29 -Input : 30 -Output : 31 -Return : 32 * Modify Date Version Author Modification 33 * ----------------------------------------------- 34 * 2017/07/28 V1.0.0 Yu Weifeng Created 35 ******************************************************************************/ 36 void MediatorExecute(T_Mediator *i_ptThis,char *i_strCmd,int i_iNum) 37 { 38 if(0==strcmp(i_strCmd,"purchase.buy")) 39 { 40 MediatorBuyComputer(i_ptThis,i_iNum); 41 } 42 else if(0==strcmp(i_strCmd,"sale.sell")) 43 { 44 MediatorSellComputer(i_ptThis,i_iNum); 45 } 46 else if(0==strcmp(i_strCmd,"sale.offsell")) 47 { 48 MediatorOffSell(i_ptThis); 49 } 50 else if(0==strcmp(i_strCmd,"stock.clear")) 51 { 52 MediatorClearStock(i_ptThis); 53 } 54 else 55 { 56 } 57 } 58 59 /***************************************************************************** 60 -Fuction : BuyComputer 61 -Description : 公有函数 62 -Input : 63 -Output : 64 -Return : 65 * Modify Date Version Author Modification 66 * ----------------------------------------------- 67 * 2017/07/28 V1.0.0 Yu Weifeng Created 68 ******************************************************************************/ 69 static void MediatorBuyComputer(T_Mediator *i_ptThis,int i_iNum) 70 { 71 int iSaleStatus=i_ptThis->tSale.GetSaleStatus(&i_ptThis->tSale); 72 int iBuyNum; 73 if(iSaleStatus>80) 74 {//销售情况良好 75 printf("采购IBM电脑%d台\r\n",i_iNum); 76 i_ptThis->tStock.Increase(&i_ptThis->tStock,i_iNum); 77 } 78 else 79 { 80 iBuyNum=i_iNum/2;//折半采购 81 printf("采购IBM电脑%d台\r\n",iBuyNum); 82 i_ptThis->tStock.Increase(&i_ptThis->tStock,iBuyNum); 83 } 84 } 85 86 /***************************************************************************** 87 -Fuction : SellComputer 88 -Description : 公有函数 89 -Input : 90 -Output : 91 -Return : 92 * Modify Date Version Author Modification 93 * ----------------------------------------------- 94 * 2017/07/28 V1.0.0 Yu Weifeng Created 95 ******************************************************************************/ 96 static void MediatorSellComputer(T_Mediator *i_ptThis,int i_iNum) 97 { 98 int iSaleStatus=i_ptThis->tSale.GetSaleStatus(&i_ptThis->tSale); 99 int iBuyNum; 100 if(i_ptThis->tStock.GetStockNum(&i_ptThis->tStock)<i_iNum) 101 {//库存数量不够 102 i_ptThis->tPurchase.BuyIBMComputer(&i_ptThis->tPurchase,i_iNum); 103 } 104 else 105 { 106 } 107 i_ptThis->tStock.Decrease(&i_ptThis->tStock,i_iNum); 108 } 109 110 /***************************************************************************** 111 -Fuction : SellComputer 112 -Description : 公有函数 113 -Input : 114 -Output : 115 -Return : 116 * Modify Date Version Author Modification 117 * ----------------------------------------------- 118 * 2017/07/28 V1.0.0 Yu Weifeng Created 119 ******************************************************************************/ 120 static void MediatorOffSell(T_Mediator *i_ptThis) 121 { 122 printf("折价销售IBM电脑%d台\r\n",i_ptThis->tStock.GetStockNum(&i_ptThis->tStock)); 123 } 124 125 /***************************************************************************** 126 -Fuction : SellComputer 127 -Description : 公有函数 128 -Input : 129 -Output : 130 -Return : 131 * Modify Date Version Author Modification 132 * ----------------------------------------------- 133 * 2017/07/28 V1.0.0 Yu Weifeng Created 134 ******************************************************************************/ 135 static void MediatorClearStock(T_Mediator *i_ptThis) 136 { 137 i_ptThis->tSale.OffSale(&i_ptThis->tSale); 138 i_ptThis->tPurchase.RefuseBuyIBM(); 139 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : MediatorPattern.h 5 * Description : 中介者模式 6 7 * Created : 2017.07.28. 8 * Author : Yu Weifeng 9 * Function List : 10 * Last Modified : 11 * History : 12 ******************************************************************************/ 13 #ifndef MEDIATOR_PATTERN_H 14 #define MEDIATOR_PATTERN_H 15 16 struct Mediator; 17 18 typedef struct Purchase 19 { 20 struct Mediator *ptMediator;//私有变量,外部禁止访问 21 void (*BuyIBMComputer)(struct Purchase *i_ptThis,int i_iNum); 22 void (*RefuseBuyIBM)(); 23 }T_Purchase; 24 25 typedef struct Stock 26 { 27 struct Mediator *ptMediator;//私有变量,外部禁止访问 28 void (*Increase)(struct Stock*i_ptThis,int i_iNum); 29 void (*Decrease)(struct Stock*i_ptThis,int i_iNum); 30 int (*GetStockNum)(struct Stock*i_ptThis); 31 void (*ClearStock)(struct Stock*i_ptThis); 32 }T_Stock; 33 34 typedef struct Sale 35 { 36 struct Mediator *ptMediator;//私有变量,外部禁止访问 37 void (*SellIBMComputer)(struct Sale *i_ptThis,int i_iNum); 38 int (*GetSaleStatus)(struct Sale *i_ptThis); 39 void (*OffSale)(struct Sale *i_ptThis); 40 }T_Sale; 41 42 typedef struct Mediator 43 { 44 T_Purchase tPurchase;//私有变量,外部禁止访问 45 T_Stock tStock;//私有变量,外部禁止访问 46 T_Sale tSale;//私有变量,外部禁止访问 47 void (*Execute)(struct Mediator *i_ptThis,char *i_strCmd,int i_iNum); 48 }T_Mediator; 49 50 void BuyIBMComputer(T_Purchase *i_ptThis,int i_iNum); 51 void RefuseBuyIBM(); 52 #define newPurchase(Mediator) {Mediator,BuyIBMComputer,RefuseBuyIBM} 53 54 void Increase(T_Stock *i_ptThis,int i_iNum); 55 void Decrease(T_Stock *i_ptThis,int i_iNum); 56 int GetStockNumber(T_Stock *i_ptThis); 57 void ClearStock(T_Stock *i_ptThis); 58 #define newStock(Mediator) {Mediator,Increase,Decrease,GetStockNumber,ClearStock} 59 60 void SellIBMComputer(T_Sale *i_ptThis,int i_iNum); 61 int GetSaleStatus(T_Sale *i_ptThis); 62 void OffSale(T_Sale *i_ptThis); 63 #define newSale(Mediator) {Mediator,SellIBMComputer,GetSaleStatus,OffSale} 64 65 66 67 void MediatorExecute(T_Mediator *i_ptThis,char *i_strCmd,int i_iNum); 68 #define newMediator(Mediator) {newPurchase(Mediator),newStock(Mediator),newSale(Mediator),MediatorExecute} 69 70 #endif
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : Purchase.c 5 * Description : 中介者模式 6 本文件是采购管理的具体实现 7 8 * Created : 2017.07.28. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include "MediatorPattern.h" 18 19 20 21 /***************************************************************************** 22 -Fuction : BuyIBMComputer 23 -Description : 公有函数 24 -Input : 25 -Output : 26 -Return : 27 * Modify Date Version Author Modification 28 * ----------------------------------------------- 29 * 2017/07/28 V1.0.0 Yu Weifeng Created 30 ******************************************************************************/ 31 void BuyIBMComputer(T_Purchase *i_ptThis,int i_iNum) 32 { 33 i_ptThis->ptMediator->Execute(i_ptThis->ptMediator,"purchase.buy",i_iNum); 34 } 35 36 /***************************************************************************** 37 -Fuction : BuyIBMComputer 38 -Description : 公有函数 39 -Input : 40 -Output : 41 -Return : 42 * Modify Date Version Author Modification 43 * ----------------------------------------------- 44 * 2017/07/28 V1.0.0 Yu Weifeng Created 45 ******************************************************************************/ 46 void RefuseBuyIBM() 47 { 48 printf("不再采购IBM电脑\r\n"); 49 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : Sale.c 5 * Description : 中介者模式 6 本文件是销售管理的具体实现 7 8 * Created : 2017.07.28. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include "MediatorPattern.h" 18 19 20 21 /***************************************************************************** 22 -Fuction : Increase 23 -Description : 公有函数 24 -Input : 25 -Output : 26 -Return : 27 * Modify Date Version Author Modification 28 * ----------------------------------------------- 29 * 2017/07/28 V1.0.0 Yu Weifeng Created 30 ******************************************************************************/ 31 void SellIBMComputer(T_Sale *i_ptThis,int i_iNum) 32 { 33 i_ptThis->ptMediator->Execute(i_ptThis->ptMediator,"sale.sell",i_iNum); 34 printf("销售IBM电脑:%d台\r\n",i_iNum); 35 } 36 37 /***************************************************************************** 38 -Fuction : Decrease 39 -Description : 公有函数 40 -Input : 41 -Output : 42 -Return : 43 * Modify Date Version Author Modification 44 * ----------------------------------------------- 45 * 2017/07/28 V1.0.0 Yu Weifeng Created 46 ******************************************************************************/ 47 int GetSaleStatus(T_Sale *i_ptThis) 48 { 49 int iStatus=95; 50 printf("IBM电脑的销售情况为:%d\r\n",iStatus); 51 return iStatus; 52 } 53 54 /***************************************************************************** 55 -Fuction : Decrease 56 -Description : 公有函数 57 -Input : 58 -Output : 59 -Return : 60 * Modify Date Version Author Modification 61 * ----------------------------------------------- 62 * 2017/07/28 V1.0.0 Yu Weifeng Created 63 ******************************************************************************/ 64 void OffSale(T_Sale *i_ptThis) 65 { 66 i_ptThis->ptMediator->Execute(i_ptThis->ptMediator,"sale.offsell",0); 67 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : Stock.c 5 * Description : 中介者模式 6 本文件是库存管理的具体实现 7 8 * Created : 2017.07.28. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> 17 #include "MediatorPattern.h" 18 19 20 static int g_iComputerNum=100; 21 /***************************************************************************** 22 -Fuction : Increase 23 -Description : 公有函数 24 -Input : 25 -Output : 26 -Return : 27 * Modify Date Version Author Modification 28 * ----------------------------------------------- 29 * 2017/07/28 V1.0.0 Yu Weifeng Created 30 ******************************************************************************/ 31 void Increase(T_Stock *i_ptThis,int i_iNum) 32 { 33 g_iComputerNum +=i_iNum; 34 printf("库存数量为:%d\r\n",g_iComputerNum); 35 } 36 37 /***************************************************************************** 38 -Fuction : Decrease 39 -Description : 公有函数 40 -Input : 41 -Output : 42 -Return : 43 * Modify Date Version Author Modification 44 * ----------------------------------------------- 45 * 2017/07/28 V1.0.0 Yu Weifeng Created 46 ******************************************************************************/ 47 void Decrease(T_Stock *i_ptThis,int i_iNum) 48 { 49 g_iComputerNum -=i_iNum; 50 printf("库存数量为:%d\r\n",g_iComputerNum); 51 } 52 53 /***************************************************************************** 54 -Fuction : Decrease 55 -Description : 公有函数 56 -Input : 57 -Output : 58 -Return : 59 * Modify Date Version Author Modification 60 * ----------------------------------------------- 61 * 2017/07/28 V1.0.0 Yu Weifeng Created 62 ******************************************************************************/ 63 int GetStockNumber(T_Stock *i_ptThis) 64 { 65 return g_iComputerNum; 66 } 67 68 /***************************************************************************** 69 -Fuction : Decrease 70 -Description : 公有函数 71 -Input : 72 -Output : 73 -Return : 74 * Modify Date Version Author Modification 75 * ----------------------------------------------- 76 * 2017/07/28 V1.0.0 Yu Weifeng Created 77 ******************************************************************************/ 78 void ClearStock(T_Stock *i_ptThis) 79 { 80 printf("清理存货数量为:%d\r\n",g_iComputerNum); 81 i_ptThis->ptMediator->Execute(i_ptThis->ptMediator,"stock.clear",0); 82 }
3)执行结果:
book@book-desktop:/work/projects/test/DesignPatterns/MediatorPattern$ gcc -o MediatorPatternUsage Purchase.c Sale.c Stock.c MediatorPattern.c MediatorPatternUsage.c
book@book-desktop:/work/projects/test/DesignPatterns/MediatorPattern$ ./MediatorPatternUsage
---------------采购人员采购电脑--------------
IBM电脑的销售情况为:95
采购IBM电脑100台
库存数量为:200
---------------销售人员销售电脑--------------
IBM电脑的销售情况为:95
库存数量为:199
销售IBM电脑:1台
---------------库房人员清库处理--------------
清理存货数量为:199
折价销售IBM电脑199台
不再采购IBM电脑
4)详细代码:
https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/BehavioralDesignPatterns/MediatorPattern
三、使用场景
类之间的依赖关系是必然存在的,并不是只要有多个依赖关系就考虑使用中介者模式(加入中介者模式有可能更复杂)。
中介者模式适用于多个对象之间紧密耦合的情况,紧密耦合的标准是:在类图中出现了蜘蛛网状结构。在这种情况下一定要考虑使用中介者模式,这有利于把蜘蛛网梳理为星型结构,使原本复杂混乱的关系变得清晰简单。
四、优点
1.中介者模式的优点就是类间的依赖,把原有的一对多的依赖变成了一对一的依赖,同事类只依赖中介者,减少了依赖,当然同时也降低了类间的耦合
五、缺点
中介者会膨胀得很大,而且逻辑复杂,原本N个对象直接的相互依赖关系转换为中介者和同事类的依赖关系,同事类越多,中介者的逻辑就约复杂
六、与其他模式的区别
1、中介者模式与门面模式的区别:
门面模式为复杂的子系统提供一个统一的访问界面,它定义的是一个高层接口,该接口使得子系统更加容易使用,避免外部模块深入到子系统内部而产生与子系统内部细节耦合的问题。
中介者模式使用一个中介对象来封装一系列同时对象的交互行为,它使各对象之间不再显式地引用,从而使其耦合松散,建立一个扩展的应用架构。
具体来说,门面模式是以封装和隔离为主要任务,而中介者模式则是以调和同事类之间的关系为主,因为要调和,所以具有了部分的业务逻辑控制。两者的主要区别如下:
1)功能区别
门面模式只是增加了一个门面,它对子系统来说没有增加任何的功能,子系统若脱离门面模式是完全可以独立运行的。
而中介者模式则增加了业务功能,它把各个同事类中的原有耦合关系移植到了中介者,同事类不可能脱离中介者而独立存在,除非是想增加系统的复杂性和降低扩展性。
2)知晓状态不同
对门面模式来说,子系统不知道有门面存在,而对中介者来说,每个同事类都知道中介者存在,因为要依靠中介者调和同时之间的关系,他们对中介者非常了解。
3)封装程度不同
门面模式是一种简单的封装,所有的请求处理都委托给子系统完成,而中介者模式则需要有一个中心,有中心协调同事类完成,并且中心本身也完成部分业务,它属于更进一步的业务功能封装