4.2 Bridge 桥模式
动机:
由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个变化的维度。
代码示例:
实现一个Messager,含有基本功能PlaySound,Connect等,并有PC、Mobile不同的平台实现 和 精简、完美等不同业务功能的版本
实现方法1:
Bridge1.cpp
类的个数:1 + n + m*n,数量巨大且不同类之中有大量重复
重构见方法2
1 class Messager{
2 public:
3 virtual void Login(string username, string password)=0;
4 virtual void SendMessage(string message)=0;
5 virtual void SendPicture(Image image)=0;
6
7 virtual void PlaySound()=0;
8 virtual void DrawShape()=0;
9 virtual void WriteText()=0;
10 virtual void Connect()=0;
11
12 virtual ~Messager(){}
13 };
14
15
16 //平台实现
17
18 class PCMessagerBase : public Messager{
19 public:
20
21 virtual void PlaySound(){
22 //**********
23 }
24 virtual void DrawShape(){
25 //**********
26 }
27 virtual void WriteText(){
28 //**********
29 }
30 virtual void Connect(){
31 //**********
32 }
33 };
34
35 class MobileMessagerBase : public Messager{
36 public:
37
38 virtual void PlaySound(){
39 //==========
40 }
41 virtual void DrawShape(){
42 //==========
43 }
44 virtual void WriteText(){
45 //==========
46 }
47 virtual void Connect(){
48 //==========
49 }
50 };
51
52
53
54 //业务抽象
55
56 class PCMessagerLite : public PCMessagerBase {
57 public:
58
59 virtual void Login(string username, string password){
60
61 PCMessagerBase::Connect();
62 //........
63 }
64 virtual void SendMessage(string message){
65
66 PCMessagerBase::WriteText();
67 //........
68 }
69 virtual void SendPicture(Image image){
70
71 PCMessagerBase::DrawShape();
72 //........
73 }
74 };
75
76
77
78 class PCMessagerPerfect : public PCMessagerBase {
79 public:
80
81 virtual void Login(string username, string password){
82
83 PCMessagerBase::PlaySound();
84 //********
85 PCMessagerBase::Connect();
86 //........
87 }
88 virtual void SendMessage(string message){
89
90 PCMessagerBase::PlaySound();
91 //********
92 PCMessagerBase::WriteText();
93 //........
94 }
95 virtual void SendPicture(Image image){
96
97 PCMessagerBase::PlaySound();
98 //********
99 PCMessagerBase::DrawShape();
100 //........
101 }
102 };
103
104
105 class MobileMessagerLite : public MobileMessagerBase {
106 public:
107
108 virtual void Login(string username, string password){
109
110 MobileMessagerBase::Connect();
111 //........
112 }
113 virtual void SendMessage(string message){
114
115 MobileMessagerBase::WriteText();
116 //........
117 }
118 virtual void SendPicture(Image image){
119
120 MobileMessagerBase::DrawShape();
121 //........
122 }
123 };
124
125
126 class MobileMessagerPerfect : public MobileMessagerBase {
127 public:
128
129 virtual void Login(string username, string password){
130
131 MobileMessagerBase::PlaySound();
132 //********
133 MobileMessagerBase::Connect();
134 //........
135 }
136 virtual void SendMessage(string message){
137
138 MobileMessagerBase::PlaySound();
139 //********
140 MobileMessagerBase::WriteText();
141 //........
142 }
143 virtual void SendPicture(Image image){
144
145 MobileMessagerBase::PlaySound();
146 //********
147 MobileMessagerBase::DrawShape();
148 //........
149 }
150 };
151
152
153 void Process(){
154 //编译时装配
155 Messager *m =
156 new MobileMessagerPerfect();
157 }
重构步骤:
1.继承转组合,将PCMessagerBase,Mobilemessager声明为字段;
1 class PCMessagerLite {
2 PCMessagerBase *messager;
3 public:
4
5 virtual void Login(string username, string password){
6
7 messager -> Connect();
8 //........
9 }
10 virtual void SendMessage(string message){
11
12 messager -> WriteText();
13 //........
14 }
15 virtual void SendPicture(Image image){
16
17 messager -> DrawShape();
18 //........
19 }
20 };
21
22 class PCMessagerLite {
23 MobileMessagerBase *messager;
24 public:
25
26 virtual void Login(string username, string password){
27
28 messager -> Connect();
29 //........
30 }
31 virtual void SendMessage(string message){
32
33 messager -> WriteText();
34 //........
35 }
36 virtual void SendPicture(Image image){
37
38 messager -> DrawShape();
39 //........
40 }
41 };
2.观察上述两个类,发现只有 *messager 声明不同,故采用基类声明,运行时多态调用方式,创建不同的 PCMessagerBase,Mobilemessager;
1 class PCMessagerLite {
2 Messager *messager; // = new PCMessagerBase()或 MobileMessagerBase()
3 public:
4
5 virtual void Login(string username, string password){
6
7 messager -> Connect();
8 //........
9 }
10 virtual void SendMessage(string message){
11
12 messager -> WriteText();
13 //........
14 }
15 virtual void SendPicture(Image image){
16
17 messager -> DrawShape();
18 //........
19 }
20 };
3.考虑步骤2的代码,Messager类是纯虚基类(抽象类),不能实例化,故= new ...不成立。
分析产生这种状况的原因,是Login,SendPicture等与平台实现相关的方法,和PlaySound,DrawShape等与业务功能相关的方法不应该在一个类里。
将其拆分,得到MessagerImp类。
同时将MessagerLite,MessagerPerfect类中相同的MesseagerImp字段提到父类Messager,得到重构后的代码
注意运行时装配
1 class Messager{
2 protected:
3 MessagerImp* messagerImp;//...
4 public:
5 virtual void Login(string username, string password)=0;
6 virtual void SendMessage(string message)=0;
7 virtual void SendPicture(Image image)=0;
8
9 virtual ~Messager(){}
10 };
11
12 class MessagerImp{
13 public:
14 virtual void PlaySound()=0;
15 virtual void DrawShape()=0;
16 virtual void WriteText()=0;
17 virtual void Connect()=0;
18
19 virtual MessagerImp(){}
20 };
21
22
23 //平台实现 n
24 class PCMessagerImp : public MessagerImp{
25 public:
26
27 virtual void PlaySound(){
28 //**********
29 }
30 virtual void DrawShape(){
31 //**********
32 }
33 virtual void WriteText(){
34 //**********
35 }
36 virtual void Connect(){
37 //**********
38 }
39 };
40
41 class MobileMessagerImp : public MessagerImp{
42 public:
43
44 virtual void PlaySound(){
45 //==========
46 }
47 virtual void DrawShape(){
48 //==========
49 }
50 virtual void WriteText(){
51 //==========
52 }
53 virtual void Connect(){
54 //==========
55 }
56 };
57
58
59
60 //业务抽象 m
61
62 //类的数目:1+n+m
63
64 class MessagerLite :public Messager {
65
66
67 public:
68
69 virtual void Login(string username, string password){
70
71 messagerImp->Connect();
72 //........
73 }
74 virtual void SendMessage(string message){
75
76 messagerImp->WriteText();
77 //........
78 }
79 virtual void SendPicture(Image image){
80
81 messagerImp->DrawShape();
82 //........
83 }
84 };
85
86
87
88 class MessagerPerfect :public Messager {
89
90
91 public:
92
93 virtual void Login(string username, string password){
94
95 messagerImp->PlaySound();
96 //********
97 messagerImp->Connect();
98 //........
99 }
100 virtual void SendMessage(string message){
101
102 messagerImp->PlaySound();
103 //********
104 messagerImp->WriteText();
105 //........
106 }
107 virtual void SendPicture(Image image){
108
109 messagerImp->PlaySound();
110 //********
111 messagerImp->DrawShape();
112 //........
113 }
114 };
115
116
117
118
119 void Process(){
120 //运行时装配
121 MessagerImp* mImp=new PCMessagerImp();
122 Messager *m =new Messager(mImp);
123 }
模式定义:
将抽象部分(业务功能)与实现部分(平台实现)分离,使他们都可以独立地变化。
类图:
要点总结:
Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象的实现可以沿着各自的维度来变化。所谓抽象和实现研制各自维度的变化,即“子类化”他们。
Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个雷只有一个变化的原因),复用性较差。Bridge模式是比多继承更好的解决方案。
Bridge模式的应用一般在“两个非常强的变化维度”有时一个类也有多余两个的变化维度,这是可以使用Bridge的扩展模式。
原文链接: https://www.cnblogs.com/wangxiaobao/p/5208448.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/229046
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!