适配器模式
理论
适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式可分为两种类型:类适配器模式和对象适配器模式。这里是以对象适配器为例。
适配器模式的应用场景:
系统的数据和行为都正确,但接口不符时,考虑使用适配器。目的是使控制范围之外的一个原有对象与某个接口匹配。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况。
(如果能事先预防接口不同的问题,不匹配问题就不会发生。在有小的接口不统一问题发生时,应该及时重构使问题不至于扩大。只有碰到无法改变原有设计和代码的情况才考虑适配。)
实例
模式教练暂停时给后卫、中锋、前锋分配进攻和防守任务。外籍中锋听不懂外语,需要翻译(在外籍中锋一时学不会英语,教练也一时学不会汉语的情况下使用)
UML类图
代码实现
#include <iostream> using namespace std; //Target class Player { public: Player(string _name) { name = _name; } virtual void Attack() = 0; virtual void Defense() = 0; protected: string name; }; class Forwards :public Player { public: Forwards(string _name) :Player(_name) {}; virtual void Attack() { cout << "前锋 " << name << " 进攻" << endl; } virtual void Defense() { cout << "前锋 " << name << " 防守" << endl; } }; class Center :public Player { public: Center(string _name) :Player(_name) {}; virtual void Attack() { cout << "中锋 " << name << " 进攻" << endl; } virtual void Defense() { cout << "中锋 " << name << " 防守" << endl; } }; class Guards :public Player { public: Guards(string _name) :Player(_name) {}; virtual void Attack() { cout << "后卫 " << name << " 进攻" << endl; } virtual void Defense() { cout << "后卫 " << name << " 防守" << endl; } }; //Adaptee class ForeignCenter { public: void SetName(string _name) { name = _name; } string GetName() { return name; } void ForeignAttack() { cout << "外籍中锋 " << name << " 进攻" << endl; } void ForeignerDefense() { cout << "外籍中锋 " << name << " 防守" << endl; } private: string name; }; //适配器类 Adapter class Translator :public Player { public: Translator(string _name) :Player(_name) { wjzf = new ForeignCenter(); wjzf->SetName(_name); } virtual void Attack() { wjzf->ForeignAttack(); } virtual void Defense() { wjzf->ForeignerDefense(); } ~Translator() { if (wjzf != NULL) { delete wjzf; } } private: ForeignCenter* wjzf; }; int main() { Player* b = new Forwards("巴蒂尔"); b->Attack(); Player* m = new Guards("麦克格雷迪"); m->Attack(); Player* ym = new Translator("姚明"); ym->Attack(); ym->Defense(); delete b; delete m; delete ym; system("pause"); return 0; }
运行结果