4.2 Bridge Mode
Motivation:
Due to certain types of intrinsic implementation logic, they have two changing dimensions, or even multiple changing dimensions.
code example:
Implementation of a messager, with basic functions playsound,connect and so on, and the PC, mobile platform implementation and streamlined, perfect and other different business functions of the version
Implementation Method 1:
Bridge1.cpp
Number of classes: 1 + n + m*n, large number of duplicates and not homogeneous
Refactoring See Method 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; Ten virtual void Connect () = 0; Virtual ~messager () {} 13}; 14 15 16//Platform Implementation Pcmessagerbase:public class messager{public:20 virtual void PlaySound () {22 $ virtual void Drawshape () {//**********-$} virtual void Writetex T () {//**********}-virtual void Connect () {31//********** 32} 33}; Mobilemessagerbase:public messager{public:37, virtual void PlaySound () {39//====== Drawshape () () (//==========) {45}-----Virtual void writetext () ========== 46} 47 virtual void Connect () {48//========== 49} 50}; 51 52 53 54//Business Abstraction-class Pcmessagerlite:public Pcmessagerbase {public:58-A-virtual void Login (s Tring Username, string password) {pcmessagerbase::connect (); 62//..... SendMessage (String message) {Pcmessagerbase::writetext (); 67/ /........ Sendpicture (image image) {pcmessagerbase::D rawshape (); 72//. ...... 73} 74}; Pcmessagerperfect:public pcmessagerbase {public:80 bayi virtual void Login (String usern AME, string password) {pcmessagerbase::P laysound (); Pcmessagerbase//******** :: Connect (); 86//..... SendMessage (String message) {pcmessagerbase::P laysound (); 91/ /******** pcmessAgerbase::writetext (); 93//..... 94} sendpicture void (image image) {pcmessagerbase::P laysound (); 98//** Pcmessagerbase::D rawshape (); 100//..... 101}102};103 104 class Mobilemessagerlite:public Mobilemessagerbase {106 public:107 108 virtual void L Ogin (string Username, string password) {109 mobilemessagerbase::connect (); 111//..... }113 virtual void SendMessage (String message) {Mobilemessagerbase::writetext (); 116 //........ 117}118 virtual void sendpicture (image image) {119 mobilemessagerbase::D rawshape (); 121 //........ 122}123};124 126 class Mobilemessagerperfect:public Mobilemessagerbase {127 public:128 129 virtual Voi D Login (string Username, string password) {131 mobilemessagerbase::P laysound (); 132//********13 3 MobilEmessagerbase::connect (); 134//..... 135}136 virtual void SendMessage (String message) {137 138 mobilemessagerbase::P laysound (); 139 Mobilemessagerbase::writetext (); 141//..... 142}143 virtual void sendpicture (image image) {144 145 mobilemessagerbase::P laysound (); 146 147 Mobilemessagerbase::D rawshape (); 148//..... 149}150};151 153 void Process () {154//compile-time assembly 155 Messager *m =156 new Mobilemessagerpe Rfect (); 157}
Refactoring steps:
1. Inherit the combination, declare Pcmessagerbase,mobilemessager as a field;
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) {messager-WRITETEXT (), 13//..... ... }15 virtual void sendpicture (image image) {messager-Drawshape (), 18//.... .}20};21 class Pcmessagerlite {mobilemessagerbase *messager;24 public:25-virtual void Login ( String username, string password) {messager, Connect (); 29//..... }31 virtual void SendMessage (String message) {messager-WRITETEXT (), 34//.... .... }36 virtual void sendpicture (image image) {messager-Drawshape (); 39//.... .}41};
2. Observing the above two classes, it is found that only *messager declaration is different, so we use the base class declaration, the runtime polymorphic call mode, and create different pcmessagerbase,mobilemessager;
1 class Pcmessagerlite {2 messager *messager;//= new Pcmessagerbase () or Mobilemessagerbase () 3 public:4 5
virtual void Login (string username, string password) {6 7 messager, Connect (); 8 //..... 9 }10 virtual void SendMessage (String message) {One - messager-WRITETEXT (); }15 virtual void sendpicture (image image) { messager-Drawshape (); ........ }20};
3. Consider the code of Step 2, the Messager class is a pure virtual base class (abstract class), cannot be instantiated, so = new ... Not set up.
The reason for the analysis is that the methods related to platform implementation such as Login,sendpicture, and the methods related to business functions such as playsound,drawshape, should not be in a class.
Split it and get the Messagerimp class.
The same messeagerimp field in the Messagerlite,messagerperfect class is referred to the parent class Messager to get the refactored code
Note Run-time assembly
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}; Each class messagerimp{public:14 virtual void PlaySound () =0; virtual void drawshape () =0; void WriteText () = 0; + virtual void Connect () = 0; Virtual Messagerimp () {} 20}; 21 22 23//Platform Implementation N class pcmessagerimp:public messagerimp{public:26 virtual void PlaySound () {28 ()-Virtual void Drawshape () {//********** +}, virtual void Writetex T () {//********** + + virtual void Connect () {37//********** 38} 39}; Mobilemessagerimp:public messagerimp{-public:43, virtual void PlaySound () {45//==== ====== 46} 47 virtual void Drawshape () {//==========}-virtual void WriteText () {51//========== 54//========== 55} 56} of the virtual void Connect () 57 58 59 60//Business abstract M 61 62//Number of classes: 1+n+m 69 class Messagerlite:p ublic messager {public:68 virtual void Login (string username, string password) {messagerimp->connect (); 72// ........ SendMessage (String message) {Messagerimp->writetext (); 77/ /........ Sendpicture (image image) {messagerimp->drawshape (); 82//. ...... 83} 84}; Messagerperfect-Class:p ublic messager {public:92 (Strin). g Username, string password) {94//******** messagerimp->playsound (); Rimp->connect (); 98 //........ }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 117 118 119 void Process () {120//runtime assembly 121 messagerimp* Mimp=new Pcmessagerimp (); 122 Mes Sager *m =new Messager (MIMP); 123}
Schema Definition:
Separate the abstract part (business function) from the implementation part (Platform implementation) so that they can all change independently.
Class Diagram:
Summary of key points:
Bridge mode uses the "Composite relationship between objects" to decouple the inherent binding relationship between abstractions and implementations, so that abstract implementations can change along their respective dimensions. The so-called abstraction and realization of the development of their respective dimensions of change, that is, "sub-class" them.
Bridge mode is sometimes similar to multiple succession scenarios, but multiple inheritance schemes often violate the single principle of responsibility (that is, a ray has only one change) and the reusability is poor. Bridge mode is a better solution than multiple inheritance.
The application of bridge mode is generally in "two very strong change dimensions" Sometimes a class also has a change dimension of two extra, which is the extension mode that can use bridge.
C + + design mode 7 (bridge bridge mode)