原来对bridge模式理解不是很深入,感觉和build模式很相似,今天又看了四人帮的关于bridge模式的描述,有些新的理解
先来说下适用性
1、不想抽象和实现之间有一个固定的绑定关系。(因为程序在运行时实现部分可以被选择或者切换)。
2、类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对他们进行扩充。(常用)
3、对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
4、你想对客户完全以藏抽象的实现部分。在c++中,类的表示在类接口中是可见的。
5、在多个对象间共享实现(可能是引用计数), 但同时要求客户并不知道这一点。
还有一种方式没理解,书上是这么说的:正如在意图一节的类图中所示的那样,有许多类要生成。这样一种类层次结构说明你必须将一个对象分解城两个部分。这种层次结构为“嵌套的普化”(nestd generalizations)***
结构图如下
示例代码如下
#include <QtCore/QCoreApplication> #include <iostream> class Implementor; // 维护一个Implementor类的指针 class Abstraction { public: Abstraction(Implementor* pImplementor); virtual ~Abstraction(); void Operation(); protected: Implementor* m_pImplementor; }; // 为实现Abstraction定义的抽象基类,定义了实现的接口函数 class Implementor { public: Implementor(){} virtual ~Implementor(){} virtual void OperationImpl() = 0; }; // 继承自Implementor,是Implementor的不同实现之一 class ConcreateImplementorA : public Implementor { public: ConcreateImplementorA(){} virtual ~ConcreateImplementorA(){} virtual void OperationImpl(); }; // 继承自Implementor,是Implementor的不同实现之一 class ConcreateImplementorB : public Implementor { public: ConcreateImplementorB(){} virtual ~ConcreateImplementorB(){} virtual void OperationImpl(); }; void ConcreateImplementorA::OperationImpl() { std::cout << "Implementation by ConcreateImplementorA\n"; } void ConcreateImplementorB::OperationImpl() { std::cout << "Implementation by ConcreateImplementorB\n"; } Abstraction::Abstraction(Implementor* pImplementor) : m_pImplementor(pImplementor) { } Abstraction::~Abstraction() { } void Abstraction::Operation() { m_pImplementor->OperationImpl(); } template <typename deleteType> inline void deleteObject(const deleteType * obj) { delete obj; obj = 0; } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); ConcreateImplementorA *pImplA = new ConcreateImplementorA(); Abstraction *pAbstraction1 = new Abstraction(pImplA); pAbstraction1->Operation(); ConcreateImplementorB *pImplB = new ConcreateImplementorB(); Abstraction *pAbstraction2 = new Abstraction(pImplB); pAbstraction2->Operation(); deleteObject(pImplB); deleteObject(pAbstraction2); deleteObject(pImplA); deleteObject(pAbstraction1); return a.exec(); }
因为Adapter中包含了一个Adaptee对象,这是一个聚合或者组合的关系。而且也是在Adapter的request方法中调用了Adaptee对象中的方法,从这个角度而言,Adapter模式和Bridge模式是非常类似的。
但是,他们之间有本质的区别:
1. 在Adapter模式中,Adaptee本身往往已经是一个具体的、已经存在的类。在Bridge模式中,Implementor则是一个抽象类或者接口;
2. 在Adapter模式中,Adapter类也是一个具体的类。在Bridge模式中,Abstraction则是一个抽象类;
3. 在Adapter模式中,Adapter类派生于一个抽象类/接口(客户程序所期望的)。在Bridge模式中,Abstraction类则不存在这样的情况。
4. 最本质同时也是最重要的区别是,它们的意图是不同的。