动机

  • 由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化。
  • 如何应对这种“多维度的变化”?如何利用面向对象技术来使得类型可以轻松地沿着两个乃至多个方向变化,而不引入额外的复杂度?

    未使用该设计模式

    ```cpp class Messager{ public: virtual void Login(string username, string passowrd) = 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 MobileMessagerBasePerfect : 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(); //… }

};

  1. <a name="MqfoM"></a>
  2. ### 实现2
  3. ```cpp
  4. class Messager{
  5. protected:
  6. MessagerImp* messagerImp; // = new PCMessagerBase();
  7. public:
  8. Messager(MessagerImp* mImp) : messagerImp(mImp){
  9. }
  10. virtual void Login(string username, string passowrd) = 0;
  11. virtual void SendMessage(string message) = 0;
  12. virtual void SendPicture(Image image) = 0;
  13. virtual ~Messager(){}
  14. };
  15. class MessagerImp{
  16. public:
  17. virtual void PlaySound() = 0;
  18. virtual void DrawShape() = 0;
  19. virtual void WriteText() = 0;
  20. virtual void Connect() = 0;
  21. virtual ~MessagerImp(){}
  22. };
  23. //平台实现
  24. class PCMessagerImp : public MessagerImp
  25. {
  26. public:
  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. class MobileMessagerImp : public MessagerImp
  41. {
  42. public:
  43. virtual void PlaySound() {
  44. //************
  45. }
  46. virtual void DrawShape() {
  47. //************
  48. }
  49. virtual void WriteText() {
  50. //************
  51. }
  52. virtual void Connect() {
  53. //************
  54. }
  55. };
  56. //业务抽象
  57. class MessagerLite : public Messager
  58. {
  59. public:
  60. MessagerLite(MessagerImp* m_Imp) : Messager(m_Imp){
  61. }
  62. virtual void Login(string username, string password){
  63. messagerImp->Connect();
  64. //...
  65. }
  66. virtual void SendMessage(string message){
  67. messagerImp->WriteText();
  68. //...
  69. }
  70. virtual void SendPicture(Image image){
  71. messagerImp->DrawShape();
  72. //...
  73. }
  74. };
  75. class MessagerPerfect : public Messager
  76. {
  77. public:
  78. virtual void Login(string username, string password){
  79. messagerImp->PlaySound();
  80. //...
  81. messagerImp->Connect();
  82. //...
  83. }
  84. virtual void SendMessage(string message){
  85. messagerImp->PlaySound();
  86. //...
  87. messagerImp->WriteText();
  88. //...
  89. }
  90. virtual void SendPicture(Image image){
  91. messagerImp->PlaySound();
  92. //...
  93. messagerImp->DrawShape();
  94. //...
  95. }
  96. };
  97. //class MobileMessagerLite
  98. //{
  99. // Messager* messager; //new ModbiMessagerBase();
  100. //public:
  101. // virtual void Login(string username, string password){
  102. // messager->Connect();
  103. // //...
  104. // }
  105. // virtual void SendMessage(string message){
  106. // messager->WriteText();
  107. // //...
  108. // }
  109. // virtual void SendPicture(Image image){
  110. // messager->DrawShape();
  111. // //...
  112. // }
  113. //
  114. //};
  115. //class MobileMessagerBasePerfect : public MobileMessagerBase {
  116. //public:
  117. // virtual void Login(string username, string password){
  118. // MobileMessagerBase::PlaySound();
  119. // //...
  120. // MobileMessagerBase::Connect();
  121. // //...
  122. // }
  123. // virtual void SendMessage(string message){
  124. // MobileMessagerBase::PlaySound();
  125. // //...
  126. // MobileMessagerBase::WriteText();
  127. // //...
  128. // }
  129. // virtual void SendPicture(Image image){
  130. // MobileMessagerBase::PlaySound();
  131. // //...
  132. // MobileMessagerBase::DrawShape();
  133. // //...
  134. // }
  135. //
  136. //};
  137. void process(){
  138. //运行时依赖
  139. MessagerImp *mImp = new PCMessagerImp();
  140. Messager *m = new MessagerLite(mImp);
  141. }

要点总结

  • Bridge模式使用“对象间地组合关键”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,即“子类化”它们。
  • Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则(即一个类只有一个变化的原因),复用性比较差。Bridge模式是比多继承方案更好的解决方法。
  • Bridge模式的应用一般在“两个非常强的变化维度:,有时一个类也有多于两个的变化维度,这时可以使用Bridge的扩展模式。