将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
该模式中有三种角色:
1、目标:是一个抽象类,它是客户想使用的接口
2、被适配者:被适配者是一个已经存在的抽象类或者是接口,需要被适配
3、适配器:适配器是一个类,它继承目标并包含有被适配者的引用。它的职责是将被适配者适配为目标
本例子中的三相电流是目标,现在有洗衣机,可以直接使用三相电流,电视机,可以使用两相电流,现在要将电视机适配为可以直接使用三相电流。实现如下:
(1)Target.h
1 #ifndef _TARGET_H_ 2 #define _TARGET_H_ 3 #include4 #include 5 using namespace std; 6 //目标 (就是适配成这样的,都使用这种) 7 class ThreeElectricOutlet{ 8 public: 9 virtual void connectElectricCurrent() = 0;10 11 };12 13 //被适配者 (现在不能使用它,把它适配为可以使用)14 class TwoElectricOutlet{15 public:16 virtual void connectElectricCurrent() = 0;17 };18 19 //适配器20 class ThreeElectricAdapter : public ThreeElectricOutlet{21 private:22 TwoElectricOutlet *myOutlet; 23 24 public:25 ThreeElectricAdapter(TwoElectricOutlet *outlet);26 void connectElectricCurrent() override;27 };28 29 //具体目标30 class Wash : public ThreeElectricOutlet{31 public:32 Wash();33 Wash(string s);34 void connectElectricCurrent() override;35 36 private:37 string name;38 39 40 };41 42 //具体被适配者43 class Tv : public TwoElectricOutlet{44 public:45 Tv();46 Tv(string s);47 void connectElectricCurrent() override;48 private:49 string name;50 51 };52 53 54 55 #endif
(2)Target.cpp
1 #include "Target.h" 2 3 ThreeElectricAdapter::ThreeElectricAdapter(TwoElectricOutlet *outlet) 4 { 5 myOutlet = outlet; 6 } 7 8 void ThreeElectricAdapter::connectElectricCurrent() 9 {10 myOutlet->connectElectricCurrent();11 }12 13 Wash::Wash()14 {15 name = "洗衣机";16 }17 Wash::Wash(string s)18 {19 name = s;20 }21 22 void Wash::connectElectricCurrent()23 {24 cout << name << "begin wash" << endl;25 }26 27 Tv::Tv()28 {29 name = "电视机";30 }31 32 Tv::Tv(string s)33 {34 name = s;35 }36 37 void Tv::connectElectricCurrent()38 {39 cout << name << "begin play video" << endl;40 }
(3)AdapterTest.cpp
1 #include "Target.h" 2 3 int main() 4 { 5 ThreeElectricOutlet *outlet; //现在只能使用的目标 其它的也将适配为这个目标 6 Wash *wash = new Wash(); //洗衣机本来就是使用的三相电(即继承的是ThreeElectricOutlet) 7 outlet = wash; 8 cout << "use three electric :" << endl; 9 outlet->connectElectricCurrent();10 11 Tv *tv = new Tv(); //电视只能使用两相电 现在将其适配为三相电12 ThreeElectricAdapter *adapter = new ThreeElectricAdapter(tv);13 outlet = adapter;14 cout << "use three electric :" << endl;15 outlet->connectElectricCurrent();16 return 0;17 }
适配器模式的关键是建立一个适配器,这个适配器继承了目标接口并且包含被适配者的引用。还可以双向适配,即使用多继承,同时继承目标和被适配者,并且包含目标和被适配者的引用。