23种设计模式(C++)之 适配器(Adapter)模式
23种设计模式(C++)之 适配器(Adapter)模式
意图
用于将一个类的接口转化成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能在一起工作的类可以一起工作。
场景
比如,当一个汽车公司收购了另一个汽车公司,两个公司的汽车管理信息系统的接口是不兼容的,中间需要连接一个适配器。
再比如,你的显示器只支持VGA接口,电脑的输出是HDMI,电脑想连接显示器,就需要先连接适配器处理一下。
再比如,手机支持5V的输入电压,家用供电电压为220V,手机想要充电就要先用适配器降压。
角色
- Target: 定义Client使用的与特定领域相关的接口。
- Client:与符合Target接口的对象协同。
- Adaptee: 定义一个已经存在的接口,这个接口需要适配。
- Adapter: 对Adaptee的接口与Target接口进行适配。
实例
- 定义目标接口:
class Target
{
public:
virtual void targetReadInfo() = 0;
};
- 具体化目标类:
class ConcreteTarget : public Target
{
public:
void targetReadInfo()
{
cout << "I'm from ConcreteTarget." << endl;
}
};
- 待适配的接口:
class Adaptee
{
public:
virtual void adapteeReadInfo() = 0;
};
- 具体化待适配的类:
class ConcreteAdaptee : public Adaptee
{
public:
void adapteeReadInfo()
{
cout << "I'm from AdapteeTarget" << endl;
}
};
- 定义适配器,有两种方式定义适配器
- 方式一(继承):
class Adapter : public ConcreteAdaptee, public Target
{
public:
void targetReadInfo()
{
this->adapteeReadInfo();
}
};
测试:
int main()
{
Target *concreteTarget = new ConcreteTarget();
concreteTarget->targetReadInfo();
Target *adapter = new Adapter();
adapter->targetReadInfo();
}
结果:
I'm from ConcreteTarget.
I'm from AdapteeTarget
- 方式二(组合):
class Adapter : public Target
{
private:
Adaptee *adaptee;
public:
Adapter(Adaptee *adaptee)
{
this->adaptee = adaptee;
}
void targetReadInfo()
{
this->adaptee->adapteeReadInfo();
}
};
测试:
int main()
{
Target *concreteTarget = new ConcreteTarget();
concreteTarget->targetReadInfo();
Target *adapter = new Adapter(new ConcreteAdaptee());
adapter->targetReadInfo();
}
结果:
I'm from ConcreteTarget.
I'm from AdapteeTarget
- 分析
(1) 对于目标接口的具体化类,直接调用targetReadInfo()即可得到目标信息;对于待适配的接口,通过调用适配器的targetReadInfo()得到目标信息。
(2) 对于继承和组合两种创建适配器类的方式,优先选择组合方式,因为继承是一种强关联,不利于管理。