设计模式之桥梁模式20170721
结构型设计模式之桥梁模式:
一、含义
桥梁模式也叫做桥接模式,其定义如下:
将抽象和实现解耦,使得两者可以独立地变化。
只要记住一句话就行:抽象角色引用实现角色,或者说抽象角色的部分实现是由实现角色完成的。
二、代码说明
1.主要有四个角色
1)抽象化角色
它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色一般是抽象类
2)实现化角色
它是接口或者抽象类,定义角色必须的行为和属性
3)修正抽象化角色
它引用实现化角色对抽象化角色进行修正
4)具体实现化角色
它实现接口或抽象类定义的方法和属性。
对于角色的理解,只要记住:抽象角色引用实现角色,或者说抽象角色的部分实现是由实现角色完成的。
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 : BridgePatternUsage.c 5 * Description : 桥梁模式的使用 6 7 book@book-desktop:/work/projects/test/DesignPatterns/BridgePattern$ gcc -o BridgePatternUsage IPodProduct.c HouseProduct.c ClothesProduct.c ShaizhaiCorp.c HouseCorp.c BridgePattern.c BridgePatternUsage.c 8 book@book-desktop:/work/projects/test/DesignPatterns/BridgePattern$ ./BridgePatternUsage 9 -----------------房地产公司是这样运行的---------------- 10 生产出房子了... 11 生产出的房子卖出去了... 12 房地产公司赚大钱了... 13 ------------------山寨公司是这样运行的----------------- 14 生产出IPod了... 15 生产出的IPod卖出去了... 16 我赚钱啊... 17 生产出衣服了... 18 生产出的衣服卖出去了... 19 我赚钱啊... 20 21 * Created : 2017.07.20. 22 * Author : Yu Weifeng 23 * Function List : 24 * Last Modified : 25 * History : 26 ******************************************************************************/ 27 #include"stdio.h" 28 #include"malloc.h" 29 #include"stdlib.h" 30 #include"string.h" 31 #include"BridgePattern.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/20 V1.0.0 Yu Weifeng Created 45 ******************************************************************************/ 46 int main(int argc,char **argv) 47 { 48 T_Product tProduct=newHouseProduct; 49 printf("-----------------房地产公司是这样运行的----------------\r\n"); 50 T_HouseCorp tHouseCorp=newHouseCorp(tProduct); 51 tHouseCorp.MakeMoney(&tHouseCorp); 52 printf("------------------山寨公司是这样运行的-----------------\r\n"); 53 tProduct=(T_Product)newIPodProduct; 54 T_ShanzhaiCorp tShanzhaiCorp=newShanzhaiCorp(tProduct); 55 tShanzhaiCorp.MakeMoney(&tShanzhaiCorp); 56 57 tProduct=(T_Product)newClothesProduct; 58 tShanzhaiCorp=(T_ShanzhaiCorp)newShanzhaiCorp(tProduct); 59 tShanzhaiCorp.MakeMoney(&tShanzhaiCorp); 60 61 62 63 return 0; 64 }
2)被调用者:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : BridgePattern.c 5 * Description : 桥梁模式 6 本文件是抽象公司类的实现 7 以公司和产品的关系举例 8 9 * Created : 2017.07.20. 10 * Author : Yu Weifeng 11 * Function List : 12 * Last Modified : 13 * History : 14 ******************************************************************************/ 15 #include"stdio.h" 16 #include"malloc.h" 17 #include"stdlib.h" 18 #include"string.h" 19 #include"BridgePattern.h" 20 21 /***************************************************************************** 22 -Fuction : MakeMoney 23 -Description : 公有函数 24 -Input : 25 -Output : 26 -Return : 27 * Modify Date Version Author Modification 28 * ----------------------------------------------- 29 * 2017/07/20 V1.0.0 Yu Weifeng Created 30 ******************************************************************************/ 31 void MakeMoney(T_Corp *i_ptThis) 32 { 33 i_ptThis->tProduct.BeProducted(); 34 i_ptThis->tProduct.BeSelled(); 35 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : BridgePattern.h 5 * Description : 桥梁模式 6 7 * Created : 2017.07.20. 8 * Author : Yu Weifeng 9 * Function List : 10 * Last Modified : 11 * History : 12 ******************************************************************************/ 13 #ifndef BRIDGE_PATTERN_H 14 #define BRIDGE_PATTERN_H 15 16 typedef struct Product 17 { 18 void (*BeProducted)(); 19 void (*BeSelled)(); 20 21 }T_Product;//实现化角色 22 23 typedef struct Corp 24 { 25 T_Product tProduct;//不同公司不同产品,所以定义在外面//构造传入,同时私有变量不可直接访问 26 27 void (*MakeMoney)(struct Corp *ptThis);//抽象出公司的职责 赚钱 28 }T_Corp;//抽象化角色 29 30 typedef struct HouseCorp 31 { 32 T_Corp tFatherCorp;//继承 33 void (*MakeMoney)(struct HouseCorp *ptThis); 34 }T_HouseCorp;//修正抽象化角色 35 36 typedef struct ShanzhaiCorp 37 { 38 T_Corp tFatherCorp; 39 void (*MakeMoney)(struct ShanzhaiCorp *ptThis); 40 }T_ShanzhaiCorp;//修正抽象化角色 41 42 void MakeMoney(T_Corp *i_ptThis); 43 44 void ShanzhaiCorpMakeMoney(T_ShanzhaiCorp *i_ptThis); 45 #define newShanzhaiCorp(Product) {Product,MakeMoney,ShanzhaiCorpMakeMoney} 46 47 void HouseCorpMakeMoney(T_HouseCorp *i_ptThis); 48 #define newHouseCorp(Product) {Product,MakeMoney,HouseCorpMakeMoney} 49 50 51 void HouseBeProducted(); 52 void HouseBeSelled(); 53 #define newHouseProduct {HouseBeProducted,HouseBeSelled} 54 55 void IPodBeProducted(); 56 void IPodBeSelled(); 57 #define newIPodProduct {IPodBeProducted,IPodBeSelled} 58 59 void ClothesBeProducted(); 60 void ClothesBeSelled(); 61 #define newClothesProduct {ClothesBeProducted,ClothesBeSelled} 62 63 64 #endif
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : HouseCorp.c 5 * Description : 桥梁模式 6 本文件是房地产公司的实现类 7 8 * Created : 2017.07.20. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include"stdio.h" 15 #include"malloc.h" 16 #include"stdlib.h" 17 #include"string.h" 18 #include"BridgePattern.h" 19 20 /***************************************************************************** 21 -Fuction : HouseMakeMoney 22 -Description : 公有函数 23 -Input : 24 -Output : 25 -Return : 26 * Modify Date Version Author Modification 27 * ----------------------------------------------- 28 * 2017/07/20 V1.0.0 Yu Weifeng Created 29 ******************************************************************************/ 30 void HouseCorpMakeMoney(T_HouseCorp *i_ptThis) 31 { 32 i_ptThis->tFatherCorp.MakeMoney(&i_ptThis->tFatherCorp); 33 printf("房地产公司赚大钱了...\r\n"); 34 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : ShanzhaiCorp.c 5 * Description : 桥梁模式 6 本文件是房地产公司的实现类 7 8 * Created : 2017.07.20. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include"stdio.h" 15 #include"malloc.h" 16 #include"stdlib.h" 17 #include"string.h" 18 #include"BridgePattern.h" 19 20 /***************************************************************************** 21 -Fuction : ShanzhaiMakeMoney 22 -Description : 公有函数 23 -Input : 24 -Output : 25 -Return : 26 * Modify Date Version Author Modification 27 * ----------------------------------------------- 28 * 2017/07/20 V1.0.0 Yu Weifeng Created 29 ******************************************************************************/ 30 void ShanzhaiCorpMakeMoney(T_ShanzhaiCorp *i_ptThis) 31 { 32 i_ptThis->tFatherCorp.MakeMoney(&i_ptThis->tFatherCorp); 33 printf("我赚钱啊...\r\n"); 34 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /***************************************************************************** 2 * Copyright (C) 2017-2018 Hanson Yu All rights reserved. 3 ------------------------------------------------------------------------------ 4 * File Module : HouseProduct.c 5 * Description : 桥梁模式 6 本文件是产品角色房子的实现类(具体实现化角色) 7 8 * Created : 2017.07.20. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include"stdio.h" 15 #include"malloc.h" 16 #include"stdlib.h" 17 #include"string.h" 18 #include"BridgePattern.h" 19 20 21 /***************************************************************************** 22 -Fuction : HouseBeProducted 23 -Description : 公有函数 24 -Input : 25 -Output : 26 -Return : 27 * Modify Date Version Author Modification 28 * ----------------------------------------------- 29 * 2017/07/20 V1.0.0 Yu Weifeng Created 30 ******************************************************************************/ 31 void HouseBeProducted() 32 { 33 printf("生产出房子了...\r\n"); 34 } 35 36 /***************************************************************************** 37 -Fuction : HouseBeSelled 38 -Description : 公有函数 39 -Input : 40 -Output : 41 -Return : 42 * Modify Date Version Author Modification 43 * ----------------------------------------------- 44 * 2017/07/20 V1.0.0 Yu Weifeng Created 45 ******************************************************************************/ 46 void HouseBeSelled() 47 { 48 printf("生产出的房子卖出去了...\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 : IPodProduct.c 5 * Description : 桥梁模式 6 本文件是产品角色IPod的实现类(具体实现化角色) 7 8 * Created : 2017.07.20. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include"stdio.h" 15 #include"malloc.h" 16 #include"stdlib.h" 17 #include"string.h" 18 #include"BridgePattern.h" 19 20 21 /***************************************************************************** 22 -Fuction : IPodBeProducted 23 -Description : 公有函数 24 -Input : 25 -Output : 26 -Return : 27 * Modify Date Version Author Modification 28 * ----------------------------------------------- 29 * 2017/07/20 V1.0.0 Yu Weifeng Created 30 ******************************************************************************/ 31 void IPodBeProducted() 32 { 33 printf("生产出IPod了...\r\n"); 34 } 35 36 /***************************************************************************** 37 -Fuction : IPodBeSelled 38 -Description : 公有函数 39 -Input : 40 -Output : 41 -Return : 42 * Modify Date Version Author Modification 43 * ----------------------------------------------- 44 * 2017/07/20 V1.0.0 Yu Weifeng Created 45 ******************************************************************************/ 46 void IPodBeSelled() 47 { 48 printf("生产出的IPod卖出去了...\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 : ClothesProduct.c 5 * Description : 桥梁模式 6 本文件是产品角色衣服的实现类(具体实现化角色) 7 8 * Created : 2017.07.20. 9 * Author : Yu Weifeng 10 * Function List : 11 * Last Modified : 12 * History : 13 ******************************************************************************/ 14 #include"stdio.h" 15 #include"malloc.h" 16 #include"stdlib.h" 17 #include"string.h" 18 #include"BridgePattern.h" 19 20 21 /***************************************************************************** 22 -Fuction : ClothesBeProducted 23 -Description : 公有函数 24 -Input : 25 -Output : 26 -Return : 27 * Modify Date Version Author Modification 28 * ----------------------------------------------- 29 * 2017/07/20 V1.0.0 Yu Weifeng Created 30 ******************************************************************************/ 31 void ClothesBeProducted() 32 { 33 printf("生产出衣服了...\r\n"); 34 } 35 36 /***************************************************************************** 37 -Fuction : ClothesBeSelled 38 -Description : 公有函数 39 -Input : 40 -Output : 41 -Return : 42 * Modify Date Version Author Modification 43 * ----------------------------------------------- 44 * 2017/07/20 V1.0.0 Yu Weifeng Created 45 ******************************************************************************/ 46 void ClothesBeSelled() 47 { 48 printf("生产出的衣服卖出去了...\r\n"); 49 }
3)执行结果:
book@book-desktop:/work/projects/test/DesignPatterns/BridgePattern$ gcc -o BridgePatternUsage IPodProduct.c HouseProduct.c ClothesProduct.c ShaizhaiCorp.c HouseCorp.c BridgePattern.c BridgePatternUsage.c
book@book-desktop:/work/projects/test/DesignPatterns/BridgePattern$ ./BridgePatternUsage
-----------------房地产公司是这样运行的----------------
生产出房子了...
生产出的房子卖出去了...
房地产公司赚大钱了...
------------------山寨公司是这样运行的-----------------
生产出IPod了...
生产出的IPod卖出去了...
我赚钱啊...
生产出衣服了...
生产出的衣服卖出去了...
我赚钱啊...
4)详细代码:
https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/StructuralDesignPatterns/BridgePattern
三、使用场景
1.不希望或不适用使用继承的场景
例如继承层次过度,无法更细化设计颗粒等场景,需要考虑使用桥梁模式。
2.接口或抽象类不稳定的场景
明知道接口不稳定还想通过实现或继承来实现业务需求,那是得不偿失的,也是比较失败的做法。
3.重用性要求较高的场景
设计的颗粒度越细,则被重用的可能性就越大,而采用继承则受父类的限制,不可能出现太细的颗粒度
4.继承与桥梁模式之间的选择
1)继承的缺点,父类有一个方法,子类也必须有这个方法,这会带来扩展性问题,比如Father类有个方法A,Son继承了这个方法,然后GrandSon也继承了这个方法,如果有一天Son要重写父类的这个方法,那么GrandSon使用的方法就会被改变(不再是从Father继承过来的方法A),这个风险太大。
2)桥梁模式就是这一问题的解决方法,桥梁模式描述了类间弱关联关系,上面例子使用桥梁模式就可以解决:Father把那个可能会变化的方法放到另一个类,其他类要使用则与那个类建立桥梁来获得。
因此,对于比较明确不发生变化的,则通过继承来完成;若不能确定是否会发生变化的,那就认为是会发生变化,则通过桥梁模式来解决。
四、优点
1.抽象和实现分离
这也是桥梁模式的主要特征,它完全是为了解决继承的缺点而提出的设计模式。在该模式下,实现可以不受抽象的约束,不用再绑定在一个固定的抽象层次上。
2.优秀的扩充能力
只要对外暴露的接口层允许这样的变化,就可以扩充。
3.实现细节对客户透明
客户不用关心细节的实现,它已经由抽象层通过聚合关系完成了封装
五、注意事项
1.使用该模式时主要考虑如何拆分抽象和实现,并不是一涉及继承就要考虑使用该模式
桥梁模式的意图还是对变化的封装,尽量把可能变化的因素封装到最细、最小的逻辑单元中,避免风险扩散。因此在进行系统设计时,发现类的继承有N层时,可以考虑使用桥梁模式。
六、与其他模式的区别
1、桥梁模式与策略模式的区别:
策略模式是一个行为模式,旨在封装一系列的行为;
而桥梁模式则是在不破坏封装的情况下抽取出它的抽象部分和实现部分,它的前提是不破坏封装,让抽象部分和实现部分都可以独立地变化。
简单来说,桥梁模式必然有两个“桥墩”---抽象化角色和实现化角色(抽象化角色(抽象的 如公司)调用实现化角色(具体的 如产品(公司生产的))),只要桥段搭建好,桥就有了,而策略模式只有一个抽象角色,可以没有实现,也可以很多实现。
2、桥梁模式与其他包装模式的区别:
自己不处理让其他人处理,这种类型的模式定义一个名字,叫做包装模式。包装模式包括:装饰模式、适配器模式、门面模式、代理模式、桥梁模式。
5个包装模式都是通过委托的方式对一个对象或一系列对象施行包装,有了包装,设计的系统才更加灵活、稳定,并且极具扩展性。从实现的角度来看,它们都是代理的一种具体表现形式,它们在使用场景上的区别如下:
1)代理模式主要用在不希望展示一个对象内部细节的场景中,此外,代理模式还可以用在一个对象的访问需要限制的场景中。
2)装饰模式是一种特殊的代理模式,它倡导的是在不改变接口的前提下为对象增强功能,或者动态添加额外职责。就扩展性而言,它比子类更灵活。
3)适配器模式的主要意图是接口转换,把一个对象的接口转换成系统希望的另外一个接口。这里的系统指的不仅仅是一个应用,也可能是某个环境,比如通过接口转换可以屏蔽外界接口,以免外界接口深入系统内部,从而提高系统的稳定性和可靠性
4)桥梁模式是在抽象层产生耦合,解决的是自行扩展的问题,它可以使两个有耦合关系的对象互不影响地扩展。
5)门面模式是一个粗粒度的封装,它提供一个方便访问子系统的接口,不具有任何的业务逻辑,仅仅是一个访问复杂系统的快速通道,没有它,子系统照样运行。