您的位置:首页 > 其它

设计模式之适配器模式

2017-08-13 15:02 169 查看

一、模式动机

  在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类。

  适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作。这就是适配器模式的模式动机。

二、模式定义

  适配器模式:将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。实际上有“两种”适配器:“对象”适配器和“类”适配器。类适配器继承被适配者和目标类,而对象适配器使用组合来适配被适配者。



三、模式示例

  还记得《Head First 设计模式》里面的鸭子,具备呱呱叫和飞行的能力,对应方法是quack()和fly()。现在要用火鸡冒充样子,但是火鸡不过呱呱叫,只会咯咯叫和飞行的能力,对应方法是gobble()和fly()。

C++代码实现

#include <iostream>

using namespace std;

class Duck
{
public:
Duck();
~Duck();
virtual void quack() = 0;
virtual void fly() = 0;

private:

};

Duck::Duck()
{
}

Duck::~Duck()
{
}

class MallardDuck : public Duck
{
public:
MallardDuck();
~MallardDuck();
void quack() { cout << "绿头鸭:呱呱叫" << endl; }
void fly() { cout << "绿头鸭:在飞行" << endl; }

private:

};

MallardDuck::MallardDuck()
{
}

MallardDuck::~MallardDuck()
{
}

class Turkey
{
public:
Turkey();
~Turkey();
virtual void gobble() = 0;
virtual void fly() = 0;

private:

};

Turkey::Turkey()
{
}

Turkey::~Turkey()
{
}

class WildTurkey : public Turkey
{
public:
WildTurkey();
~WildTurkey();
void gobble() { cout << "野火鸡:咯咯叫" << endl; }
void fly() { cout << "野火鸡:在飞行" << endl; }

private:

};

WildTurkey::WildTurkey()
{
}

WildTurkey::~WildTurkey()
{
}

class TurkeyAdapter : public Duck
{
public:
TurkeyAdapter(Turkey* turkey);
~TurkeyAdapter();
void quack() { turkey_->gobble(); }
void fly() { turkey_->fly(); }

private:
Turkey* turkey_;

};

TurkeyAdapter::TurkeyAdapter(Turkey* turkey)
:turkey_(turkey)
{
}

TurkeyAdapter::~TurkeyAdapter()
{
}

int _tmain(int argc, _TCHAR* argv[])
{
MallardDuck duck;
duck.fly();
duck.quack();
WildTurkey turkey;
Duck* turkeyAdapter = new TurkeyAdapter(&turkey);
turkeyAdapter->fly();
turkeyAdapter->quack();
system("pause");
return 0;
}


运行结果:



四、分析总结

  适配器模式有两种形式:对象适配器和类适配器。类适配器需要用到多重继承。

优点:

将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。

增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。

灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: