设计模式---接口隔离模式之适配器模式(Adapter)
一:概念
通过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)的更多相关文章
- 设计模式---接口隔离模式之门面模式(Façade)
前提:接口隔离模式 在组建构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接接口(稳定的),来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式: 门面模 ...
- 设计模式---接口隔离模式之中介者模式(Mediator)
一:概念 在Mediator模式中,类之间的交互行为被统一放在Mediator的对象中,对象通过Mediator对象同其他对象交互.Mediator对象起到控制器的作用 二:动机 在软件构建的过程中, ...
- 设计模式---接口隔离模式之代理模式(Proxy)
一:概念 代理模式(Proxy Pattern)就是为其他对象提供一种代理以控制对这个对象的访问. 比如: 智能指针 为别人做嫁衣 所谓代理,是指具有与代理元(被代理的对象)具有相同的接口的类,客户端 ...
- 设计模式---结构型模式之适配器模式(Adapter Pattern)
适配器模式定义 将一个类的接口,转换成客户期望的另外一个接口.适配器让原本接口不兼容的类可以合作无间. 适配器模式主要有两种类型:对象适配器和类适配器. 在详细解释这两种类型时,解释部分重要角色.生活 ...
- C++设计模式 之 “接口隔离” 模式:Facade、Proxy、Mediator、Adapter
“接口隔离”模式 在组建构建过程中,某些接口之间之间的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接(稳定)接口,来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式 #Facad ...
- 23种设计模式 - 接口隔离(Facade - Proxy - Mediator - Adapter)
其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 接口隔离 在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接( ...
- 七个结构模式之适配器模式(Adapter Pattern)
定义: 将一个接口转换为客户需要的另外一个接口,使接口不兼容的类型可以一起工作,也被称为包装器模式(Wrapper Patern). 结构图: Target:目标抽象类,客户所需要的接口. Adapt ...
- 设计模式 第一天 UML图,设计模式原则:开闭原则、依赖倒转原则、接口隔离原则、合成复用原则、迪米特法则,简单工厂模式
1 课程大纲 2 UML的概述 总结: UML unified model language 统一建模语言 一共有十种图: 类图 用例图 时序图 * 对象图 包图 组件图 部署图 协作图 状态图 (最 ...
- 设计模式(五)适配器模式Adapter(结构型)
设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...
随机推荐
- BZOJ3790神奇项链——manacher+贪心
题目描述 母亲节就要到了,小 H 准备送给她一个特殊的项链.这个项链可以看作一个用小写字 母组成的字符串,每个小写字母表示一种颜色.为了制作这个项链,小 H 购买了两个机器.第一个机器可以生成所有形式 ...
- mpvue——引入antv-F2图表
踩坑中~ 官方文档 https://www.yuque.com/antv/f2/intro 毕竟不像echarts接触过,所以还是先看看文档较好 github https://github.com/s ...
- 洛谷P4581 [BJOI2014]想法(玄学算法,拓扑排序)
洛谷题目传送门 萝卜大毒瘤 题意可以简化成这样:给一个DAG,求每个点能够从多少个入度为\(0\)的点到达(记为\(k\)). 一个随机做法:给每个入度为\(0\)的点随机一个权值,在DAG上求出每个 ...
- Codeforces Round #449 (Div. 1) Willem, Chtholly and Seniorious (ODT维护)
题意 给你一个长为 \(n\) 的序列 \(a_i\) 需要支持四个操作. \(1~l~r~x:\) 把 \(i \in [l, r]\) 的 \(a_i\) 加 \(x\) . \(2~l~r~x: ...
- 聊聊openjdk的BufferPoolMXBean
本文主要研究一下openjdk的BufferPoolMXBean PlatformManagedObjectjava.management/java/lang/management/PlatformM ...
- linux中监控CPU、内存和磁盘状态的shell脚本。(centos7)
这篇博客中所写的脚本,在实际工作中并没有什么卵用,工作中并不会用到这种脚本去监控.不过自己写一遍,可以让初学者对CPU.内存.磁盘等一些基础知识和基础命令更加了解. 1.利用vmstat工具监控CPU ...
- Codeforces Round #555 (Div. 3)[1157]题解
不得不说这场div3是真的出的好,算得上是从我开始打开始最有趣的一场div3.因为自己的号全都蓝了,然后就把不经常打比赛的dreagonm的号借来打这场,然后...比赛结束rank11(帮dreago ...
- EasyFlash 的初始化配置
@2019-02-18 [小记] EasyFlash的初始化流程 easyflash_init ---> ef_port_init ---> sfud_init ---> sfud_ ...
- Vagrant将下载好的镜像装载到本地中
Vagrant box add centos7 ${path}CentOS-7-x86_64-Vagrant-1803_01.VirtualBox Vagrant init ${名字} Vagrant ...
- User Agent 用户代理
User Agent中文名为用户代理,简称 UA,它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本.CPU 类型.浏览器及版本.浏览器渲染引擎.浏览器语言.浏览器插件等. User A ...