设计动机
- 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个纬度的变化
- 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?
定义
将抽象部分业务功能)与实现部分(平台实现)分离,使它们都可以独立地变化。
结构
例子
传统继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
| class Messager{ public: virtual void Login(string username, string password)=0; virtual void SendMessage(string message)=0; virtual void SendPicture(Image image)=0;
virtual void PlaySound()=0; virtual void DrawShape()=0; virtual void WriteText()=0; virtual void Connect()=0; virtual ~Messager(){} };
class PCMessagerBase : public Messager{ public: virtual void PlaySound(){ } virtual void DrawShape(){ } virtual void WriteText(){ } virtual void Connect(){ } };
class MobileMessagerBase : public Messager{ public: virtual void PlaySound(){ } virtual void DrawShape(){ } virtual void WriteText(){ } virtual void Connect(){ } };
class PCMessagerLite : public PCMessagerBase { public: virtual void Login(string username, string password){ PCMessagerBase::Connect(); } virtual void SendMessage(string message){ PCMessagerBase::WriteText(); } virtual void SendPicture(Image image){ PCMessagerBase::DrawShape(); } };
class PCMessagerPerfect : public PCMessagerBase { public: virtual void Login(string username, string password){ PCMessagerBase::PlaySound(); PCMessagerBase::Connect(); } virtual void SendMessage(string message){ PCMessagerBase::PlaySound(); PCMessagerBase::WriteText(); } virtual void SendPicture(Image image){ PCMessagerBase::PlaySound(); PCMessagerBase::DrawShape(); } };
class MobileMessagerLite : public MobileMessagerBase { public: virtual void Login(string username, string password){ MobileMessagerBase::Connect(); } virtual void SendMessage(string message){ MobileMessagerBase::WriteText(); } virtual void SendPicture(Image image){ MobileMessagerBase::DrawShape(); } };
class MobileMessagerPerfect : public MobileMessagerBase { public: virtual void Login(string username, string password){ MobileMessagerBase::PlaySound(); MobileMessagerBase::Connect(); } virtual void SendMessage(string message){ MobileMessagerBase::PlaySound(); MobileMessagerBase::WriteText(); } virtual void SendPicture(Image image){ MobileMessagerBase::PlaySound(); MobileMessagerBase::DrawShape(); } };
void Process(){ Messager *m = new MobileMessagerPerfect(); }
|
桥模式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| class Messager{ protected: MessagerImp* messagerImp; public: virtual void Login(string username, string password)=0; virtual void SendMessage(string message)=0; virtual void SendPicture(Image image)=0; virtual ~Messager(){} };
class MessagerImp{ public: virtual void PlaySound()=0; virtual void DrawShape()=0; virtual void WriteText()=0; virtual void Connect()=0; virtual MessagerImp(){} };
class PCMessagerImp : public MessagerImp{ public: virtual void PlaySound(){ } virtual void DrawShape(){ } virtual void WriteText(){ } virtual void Connect(){ } };
class MobileMessagerImp : public MessagerImp{ public: virtual void PlaySound(){ } virtual void DrawShape(){ } virtual void WriteText(){ } virtual void Connect(){ } };
class MessagerLite :public Messager {
public: virtual void Login(string username, string password){ messagerImp->Connect(); } virtual void SendMessage(string message){ messagerImp->WriteText(); } virtual void SendPicture(Image image){ messagerImp->DrawShape(); } };
class MessagerPerfect :public Messager { public: virtual void Login(string username, string password){ messagerImp->PlaySound(); messagerImp->Connect(); } virtual void SendMessage(string message){ messagerImp->PlaySound(); messagerImp->WriteText(); } virtual void SendPicture(Image image){ messagerImp->PlaySound(); messagerImp->DrawShape(); } };
void Process(){ MessagerImp* mImp=new PCMessagerImp(); Messager *m =new Messager(mImp); }
|
总结
- Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自纬度的变化,即“子类化”它们。
- Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
- Bridge模式的应用一般在“两个非常强的变化维度”,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。