一:概念

通过Adapter模式可以改变已有类(或外部类)的接口形式

二:动机

在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。
如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?
生活中如电源适配器,vga转换线等,适配器模式可以通过将旧的类接口转化为新接口,从而解决新环境要求的接口问题。

三:模式定义

将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
                                       --《设计模式》Gof

四:类图(结构)

五:代码讲解

//目标接口(新接口)
class ITarget{
public:
virtual void process()=;
}; //遗留接口(老接口)
class IAdaptee{
public:
virtual void foo(int data)=;
virtual int bar()=;
}; //遗留类型,符合老的接口
class OldClass: public IAdaptee{
//....
}; //对象适配器
class Adapter: public ITarget{ //继承
protected:
IAdaptee* pAdaptee;//组合
public: Adapter(IAdaptee* pAdaptee){
this->pAdaptee=pAdaptee;
} virtual void process(){
int data=pAdaptee->bar();
pAdaptee->foo(data); }
};
int main(){
IAdaptee* pAdaptee=new OldClass(); ITarget* pTarget=new Adapter(pAdaptee);
pTarget->process();
}
接口转换,将目标接口转目的接口,不一定是旧的旧和新,例如栈和队列转换,本身即是接口又是实现。
class stack{  //没有组合,没有指针,即是接口又是实现
deqeue container; }; class queue{
deqeue container; };

六:要点总结

(一)Adapter模式主要应用于“希望复用一些现存的类,但是接口又与服用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。

(二)GoF23定义了两种Adapter模式的结构实现:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合的精神。

1.对象适配器

//对象适配器
class Adapter: public ITarget{ //继承
protected:
IAdaptee* pAdaptee;//组合,灵活性高 public: Adapter(IAdaptee* pAdaptee){
this->pAdaptee=pAdaptee;
} virtual void process(){
int data=pAdaptee->bar();
pAdaptee->foo(data); }
};
一个继承一个组合,就叫做对象适配器:因为他是通过组合对象来实现适配的

2.类适配器(不太好,用的很少,坏处更多)

//类适配器
class Adapter: public ITarget,
protected OldClass{ //多继承,定死了,灵活性不高
}
通过多继承来实现类适配器,public继承是共有接口,我符合你的接口规范,protected和private继承是实现继承,并没有继承你的接口,但是我用你的实现

(三)Adapter模式可以实现的非常灵活,不必拘泥于GoF23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。

七:案例实现:电压转换18-220v

class Current18V
{
public:
virtual void use18vCurrent()
{
cout << "use 18v voltage" << endl;
}
}; class Current220V
{
public:
void use220vCurrent()
{
cout << "use 220v voltage" << endl;
}
};
//继承接口规范,组合数据
class Adapter :public Current18V
{
private:
Current220V* cur;
public:
Adapter(Current220V* c) :cur(c)
{
} virtual void use18vCurrent()
{
cout << "adapter use voltage" << endl;
cur->use220vCurrent();
}
};
void main()
{
Current220V* c2 = new Current220V();
Adapter* adapter = new Adapter(c2);
adapter->use18vCurrent(); delete c2;
delete adapter; system("pause");
return;
}

设计模式---接口隔离模式之适配器模式(Adapter)的更多相关文章

  1. 设计模式---接口隔离模式之门面模式(Façade)

    前提:接口隔离模式 在组建构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接接口(稳定的),来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式: 门面模 ...

  2. 设计模式---接口隔离模式之中介者模式(Mediator)

    一:概念 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互.Mediator对象起到控制器的作用 二:动机 在软件构建的过程中, ...

  3. 设计模式---接口隔离模式之代理模式(Proxy)

    一:概念 代理模式(Proxy Pattern)就是为其他对象提供一种代理以控制对这个对象的访问. 比如: 智能指针 为别人做嫁衣 所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端 ...

  4. 设计模式---结构型模式之适配器模式(Adapter Pattern)

    适配器模式定义 将一个类的接口,转换成客户期望的另外一个接口.适配器让原本接口不兼容的类可以合作无间. 适配器模式主要有两种类型:对象适配器和类适配器. 在详细解释这两种类型时,解释部分重要角色.生活 ...

  5. C++设计模式 之 “接口隔离” 模式:Facade、Proxy、Mediator、Adapter

    “接口隔离”模式 在组建构建过程中,某些接口之间之间的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接(稳定)接口,来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式 #Facad ...

  6. 23种设计模式 - 接口隔离(Facade - Proxy - Mediator - Adapter)

    其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 接口隔离 在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接( ...

  7. 七个结构模式之适配器模式(Adapter Pattern)

    定义: 将一个接口转换为客户需要的另外一个接口,使接口不兼容的类型可以一起工作,也被称为包装器模式(Wrapper Patern). 结构图: Target:目标抽象类,客户所需要的接口. Adapt ...

  8. 设计模式 第一天 UML图,设计模式原则:开闭原则、依赖倒转原则、接口隔离原则、合成复用原则、迪米特法则,简单工厂模式

    1 课程大纲 2 UML的概述 总结: UML unified model language 统一建模语言 一共有十种图: 类图 用例图 时序图 * 对象图 包图 组件图 部署图 协作图 状态图 (最 ...

  9. 设计模式(五)适配器模式Adapter(结构型)

      设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...

随机推荐

  1. js弹框的3种方法

    js的三种弹框的方法 1.第一种 :  alert("1"); 2.第二种 :  window.open("Tests2.html"); var r = con ...

  2. Luogu5205 【模板】多项式开根(NTT+多项式求逆)

    https://www.cnblogs.com/HocRiser/p/8207295.html 安利! 写NTT把i<<=1写成了i<<=2,又调了一年.发现我的日常就是数组开 ...

  3. jquery 循环绑定click的问题

    之前循环数据,通过live绑定click, 发觉每个click绑定的链接参数都是一样的. 后来改用 直接的 click绑定,就好了. $.each(ship.PPRList, function (i, ...

  4. 洛谷3822 [NOI2017] 整数 【线段树】【位运算】

    题目分析: 首先这题的询问和位(bit)有关,不难想到是用线段树维护位运算. 现在我们压32位再来看这道题. 对于一个加法操作,它的添加位置可以得到,剩下的就是做不超过32的位移.这样根据压位的理论. ...

  5. 「浙大ACM」图森未来杯游记一篇以及简易口胡题解

    前言 蒟蒻有参加了ACM比赛,这一次有适合HY和慕容宝宝大佬一起比的,他们好巨啊,把我带飞了. 又是窝掌机,QAQ,他们仗着自己巨,就欺负窝... 我又打了\(4\)个小时的代码,而且那个键盘太恶心了 ...

  6. GuGuFishtion HDU - 6390 (杭电多校7E)

    啊啊啊啊...全在纸上 字丑...算了算了 然后除法部分都用逆元就好了 还有逆元打表....学到了...牛逼 #include<map> #include<set> #incl ...

  7. JetBrains全家桶破解思路(最新更新:2019-04-17)

    JetBrains全家桶破解思路(以DataGrip为例) 2019-04-17 add new key 2019-01-24 add new key and code 2018-12-24 add ...

  8. logback 设置按天,文件切割大小,总共日志文件大小。

    设置按天,文件切割大小,总共日志文件大小. <?xml version="1.0" encoding="UTF-8"?> <configura ...

  9. 遍历HTML DOM 树

    <!-- NodeIterator --> <!DOCTYPE html> <html> <head> <meta charset="u ...

  10. BZOJ3881 Divljak

    解:对被包含的那些串建AC自动机. 每次加一个串,就在AC自动机上面跑,可知能够跑到一些节点. 这些节点都是一些前缀的形式,我们跳fail树就是跳后缀,这样就能够得到所有能匹配的子串. 我们分别对AC ...