喜欢美食, 旅行..
分类: C/C++
2013-02-07 16:29:38
1. 意图
将一个类的接口转换成客户希望的另外一个接口. Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.
2. 面向对象设计原则
最少知识原则, 即暴露在外的信息量最少越好, 例如 类Adapter 在实现的时候应该用私有的方式继承 Adaptee.
3. 适用性
* 你想使用一个已存在的类, 而它的接口不符合你的要求.
* 你想创建一个可以复用的类, 该类可以与其他不相关的类或不可预见的类 ( 即可能不一定兼容的类 ) 协同工作.
* ( 仅适用于对象 Adapter ) 你想使用一些已经存在的子类, 但是不可能对每一个都进行子类化以匹配它们的接口. 对象适配器可以适配它的父类接口.
4. 类层次结构图
a. 类 Adapter. 用多重继承 使得 一个接口与另一个接口进行匹配. 如下:
b. 对象 Adapter. 对象适配器依赖于对象组合. 如下:
5. 实现
尽管 Adapter 的实现方式通常简单直接, 但是任然需要注意下面问题:
* 使用 C++ 实现类 Adapter 的时候, 应该要采用公共方式继承 Target 类, 并且使用私有方式继承 Adaptee 类. 因此, Adapter 类应该是 Target 的子类性, 但不是 Adaptee 的子类性.
* 还有一种叫做双向适配器的类 Adapter. 它对要适配的双方都采用公共的方式继承, 从而达到双向适配的效果, 但是不多见.
* 可插入的适配器, 又叫内部接口适配器.
a. 首先是要为 Adapter 找到一个 "窄" 接口, 即可用于适配的最小操作集. 例如: 层次式结构中, 最小接口集合应该包括两个, 一个定义如何在层次结构中表示一个节点, 另一个返回该节点的子节点.
b. 然后针对这些 "窄" 接口实现可插入的适配器, 方法有三 ( 这里以树结构的层次结构为例 ):
第一个, 使用抽象操作, 定义 "窄" 接口集对应的抽象操作集合, 然后由子类来实现这些抽象操作, 并匹配具体的树结构的对象.
第二个, 使用代理对象, 用代理类来继承 " 窄 " 接口集合, 并实现集合的所有接口.
第三个, 参数化的适配器, "窄" 接口集合的每一个接口都用一个模块或者参数来表示, 即把接口及和参数化.
6. 样例代码
比如我们现在要简单的把一只狗适配成一只猫, 好让它抓一只老鼠. 已知 实现狗的代码 如下:
class Dog { public: Dog(){} virtual ~Dog(){} virtual void StandUp(){ cout << " stand up. " << endl; } virtual void Run(){ cout << " run and run. " << endl; } virtual void Singing(){ cout << " sings : wang~wang~wang~~. " << endl; } };我们先用类 Adapter 来实现一次
class Cat { public: Cat(){} virtual ~Cat(){} virtual void CatchMouse() = 0; }; class MyCat :public Cat, private Dog { public: virtual void CatchMouse() { Dog::StandUp(); Dog::Run(); cout << " catched a mouse" << endl; } }; void main() { Cat * cat = new MyCat; cat->CatchMouse(); }
我们在用对象 Adapter 来实现一次
class Cat { public: Cat(){} virtual ~Cat(){} virtual void CatchMouse() = 0; }; class MyCat :public Cat, private Dog { Dog dog; public: virtual void CatchMouse() { dog.StandUp(); dog.Run(); cout << " catched a mouse" << endl; } }; void main() { Cat * cat = new MyCat; cat->CatchMouse(); }