简介
适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作
适配器模式的别名为包装器(Wrapper)模式,它既可以作为类结构型模式,也可以作为对象结构型模式。在适配器模式定义中所提及的接口是指广义的接口,它可以表示一个方法或者方法的集合。
结构:
- 客户端使用的Target类需要使用一个已经存在的接口Adaptee类,可以用两种方法实现:
- 1、构造Adapter类继承Target类,并实现Adaptee接口(适配器模式的类版本)
- 2、将一个Adaptee实例作为Adapter的组成部分(适配器模式的对象版本)
类适配器模式结构图:
对象适配器结构图:
适配器模式的适用性:
- 想使用一个已经存在的类,但它的接口不符合需求。
- 想创建一个可以复用的类,该类可以与其它不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
- 想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
具体可参考:
实例
分别利用类版本和对象版本的适配器模式模拟实现ps2接口和usb接口的转换。
我们手中有个ps2插头的设备,但是主机上只有usb插头的接口,实现一个适配器将ps2接口转换为usb接口。其中,ps2接口表示为:
1 2 3 4 5 6 7 |
class Ps2{ virtual void isPs2(); } class Usb{ Virtual void isusb(); }。 |
实验UML图
代码
- target为:usb
- Adaptee为:Ps2
- Adapter类公有继承target,私有继承Adaptee
类适配器模式代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include<iostream> using namespace std; /* 分别利用类版本和对象版本的适配器模式模拟实现ps2接口和usb接口的转换。 我们手中有个ps2插头的设备,但是主机上只有usb插头的接口,实现一个适配器将ps2接口转换为usb接口。其中,ps2接口表示为: class Ps2{ virtual void isPs2(); } Usb接口表示为: class Usb{ Virtual void isusb(); }。 */ class Usb{ //target public: virtual void isusb(){ cout<<"USB接口"<<endl; }; }; class Ps2{ //adaptee public: void isPs2(){ cout<<"Ps2"<<endl; }; }; class Adapter: public Usb, private Ps2{ void isusb(){ isPs2(); } }; int main(){ Usb* usb = new Adapter(); usb->isusb(); return 0; } |
对象适配器代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#include<iostream> using namespace std; class Ps2{ //adaptee public: void isPs2(){ cout<<"Ps2"<<endl; }; }; class Usb{ //target public: virtual void isusb(){ cout<<"USB接口"<<endl; }; }; class Adapter: public Usb{ public: void isusb(){ ps2->isPs2(); } private: Ps2 * ps2 = new Ps2(); }; int main(){ Usb* usb = new Adapter(); usb->isusb(); return 0; } |
两个均调用的为SpecificRequest();
总结
①本次实验掌握并编码了适配器模式的类与对象的两种不同方法。
②在实现类适配器和对象适配器时,注意,对象适配器模式中的“目标接口”和“适配者类”的代码同类适配器模式一样,只要修改适配器类和客户端的代码即可。