喜欢美食, 旅行..
分类: C/C++
2013-02-07 12:06:52
1. 意图
将抽象部分与它的实现部分分离, 使它们都可以独立变化, 相比继承而言有更大的灵活度.
2. 面向对象设计原则
好莱坞原则:别调用我, 我会调用你的. ( 防止依赖腐败, 只能让 Handle 调用 Body ).
3. 适用性
* 你不希望在抽象和他的实现之间有一个固定的绑定关系. 例如这种情况可能是因为, 在程序运行时刻, 实现部分应可以被切换或者选择.
* 类的抽象以及它的子类都可以通过生成子类的方式扩充. 这时 Bridge 模式可以使你对不同的抽象接口和实现部分组合, 并分别对它们扩充.
* 对一个抽象的实现部分的修改应对客户程序不产生影响, 即客户的代码不必重现编译.
* 你想对客户完全隐藏抽象的实现部分. ( C++ 类的表示在接口是可见的 )
* 你有许多的子类要生成, 必须将一个对象一分为二以实现 "嵌套的普化" ( Nested generalizations ).
* 你想在多个对象间共享实现 ( 可能使用引用计数 ), 但同时要求客户并不知道这一点.
4. 类层次结构图
5. 实现
使用 Bridge 模式的时候需要注意下面几点:
* 仅有一个实现的时候, 没有必要创建一个抽象的 Implementor 类. 这是 Bridge 的退化情况, 在 Abstraction 和 Implementor 之间有一种一对一的关系.
* 当存在多个 Implementor 类的时候, 你可以尝试下面的方式:
a. 如果 Abstraction 知道所有的 ConcreteImplementor, 它就可以在它的构造器中对其中的一个进行实例化, 它可以通过传递给构造器的参数确定应该实例化哪一个.
b. 首先选择一个缺省的实现, 然后根据需要 ( 缺省实现不能满足需求的时候 ) 改变这个实现.
c. 代理给另一个对象, 让它一次性决定. 例如, 我们可以引入一个 Factory 对象 ( 抽象工厂设计模式 ), 该对象的唯一职责就是创建各种 ConcreteImplementor.
* 共享 Implementor 的时候, 需要实现一个对象引用计数器. 和智能指针 shared_ptr 的实现原理类似.
* C++ 中可以使用多重继承机制将抽象接口和它的实现部分结合起来. 例如, 一个类可以使用 public 方式继承 Abstraction 而以 private 方式继承 ConcreteImplementor. 但是, 由于这种方法依赖于静态继承, 它将实现部分与接口部分固定不变的绑定在一起, 因此, 不可能使用多重继承实现真正的 Bridge 模式, 至少用 C++ 不行.
6. 样例代码
估计网友看完上面的长篇大论快要骂娘了. 下面附上一份简单的实现, 希望共勉之.
// Animal.h
#include"AnimalImp.h" class Animal { protected: templateAnimalImp * GetAnimalImp() { return new TypeAnimalImp; } public: Animal() { } virtual ~Animal() { } virtual void MusicAction() = 0; };
//AnimalImp.h
class AnimalImp { public: AnimalImp() { } virtual ~AnimalImp() { } virtual void StandUp() = 0; virtual void Dancing() = 0; virtual void Singing() = 0; };
// Duck.h
#include “Animal.h” #include “DuckImp.h” class Duck : public Animal { public: Duck(){ } virtual ~Duck(){} virtual void MusicAction() { AnimalImp * ptrImp = GetAnimalImp(); ptrImp->StandUp(); size_t time = 10; while( --time > 0 ) { ptrImp->Dancing(); ptrImp->Singing(); ptrImp->Singing(); } delete ptrImp; } };
// DuckImp.h
#include#include "AnimalImp.h" class DuckImp : public AnimalImp { public: DuckImp() : AnimalImp(){} virtual ~DuckImp(){} virtual void StandUp(){ cout << " the duck stand up. " << endl; } virtual void Dancing(){ cout << " the duck rickety shuttlecock. " << endl; } virtual void Singing(){ cout << " the duck sings : ga~ga~ga~~. " << endl; } };
// Dog.h
#include "Animal.h" #include "DogImp" class Dog : public Animal { public: Dog() { } virtual ~Dog() { } virtual void MusicAction() { AnimalImp * ptrImp = GetAnimalImp(); ptrImp->StandUp(); size_t time = 10; while( --time > 0 ) { ptrImp->Dancing(); ptrImp->Dancing(); ptrImp->Singing(); } delete ptrImp; } };
// DogImp.h
#includeclass DogImp : public AnimalImp { public: DogImp() : AnimalImp(){} virtual ~DogImp(){} virtual void StandUp(){ cout << " the dog stand up. " << endl; } virtual void Dancing(){ cout << " the dog run and run. " << endl; } virtual void Singing(){ cout << " the dog sings : wang~wang~wang~~. " << endl; } };
// main.cpp
#include "Dog.h" #include "Duck.h" void main() { Duck animal; animal.MusicAction(); Dog animal2; animal2.MusicAction(); }