桥模式
"单一职责"模式: 在软件组件的设计中,如果职责划分不清晰,继续继承得到的结果往往时随着需求的变化,子类急剧膨胀,同时充斥着重复代码, 这时候的关键时华清职责。
动机:
由于某些类型的固有的实现逻辑,使得他们具有两个变化的维度,
乃至多个维度的变化。
如何应对这种"多维度的变化"? 如何利用面向对象技术来使得类型可以轻松沿着两个乃至多个方向上变化,而不引入额外的复杂度。
例:这是一个消息基类,
如需要在PC上实现一套功能,定义PCMessage继承Message 类并重写虚函数。
如需要在Mobile实现一套功能,定义MobileMessage继承Message类并重写虚函数。
...
我们需要在不通维度上拆分成两个类,使用时,再组合。
//定义消息业务基类 class MessageImp{ public: virtual void PlaySound() = 0; virtual void DrawShape() = 0; virtual void Connect() = 0; ~MessageImp(){} } // 定义消息基类 class Message{ protected: MessageImp * m_message; // 定义为基类,用于子类多态调用。组合效果优于继承 public: Message(MessageImp * p):m_message(p){ } virtual void Login(const string& strUserName,const string& password) = 0; ~Message(){} }
//PC业务类 class PCMessageImp : pubilc MessageImp{ public: virtual void PlaySound(){} virtual void DrawShape(){} virtual void Connect(){} } //Mobaile业务类 class MobaileMessageImp : pubilc MessageImp{ public: virtual void PlaySound(){} virtual void DrawShape(){} virtual void Connect(){} } //消息业务类 class MessageLite : pubilc Message{ MessageLite(MessageImp * p):Message(p){ } public: virtual void Login(const string& strUserName,const string& password){ //... m_message->connect(); m_message->PlaySound(); m_message->DrawShape(); } }
//调用业务 void Process(const string& strUserName,const string& password){ MessageImp * pImp = new PCMessageImp(); Message * pLite = MessageLite(pImp); pLite->Login(strUserName, password); }
总结: Bridge模式使用"对象间的组合关系", 解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。 所谓抽象和实现沿着各自维度的变化,即"子类化"他们。 Bridge模式有时候类似于多继承方案,但是多继承方案往往违背单一职责原则,服用性比较差。 Bridge模式是比多继承方案更好的解决方案。 Bridge模式的应用一般在"两个非常强的变化维度", 有时一个类也有多于两个的变化维度, 这是可以使用Bridge的扩展模式。