在 Adapter 模式的结构图中可以看到,类模式的 Adapter 采用继承的方式复用 Adaptee
的接口,而在对象模式的 Adapter 中我们则采用组合的方式实现 Adaptee 的复用

类模式的adapter

#include<iostream>

using namespace std;

class Target
{
public:
Target();
virtual ~Target();
virtual void Request();
protected:
private:
};
class Adaptee
{
public:
Adaptee();
~Adaptee();
void SpecificRequest();
protected:
private:
};
class Adapter:public Target,private Adaptee
{
public:
Adapter();
~Adapter();
void Request();
protected:
private:
}; Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
std::cout<<"Target::Request"<<std::endl;
}
Adaptee::Adaptee()
{ } Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<
std::endl;
}
Adapter::Adapter()
{
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
this->SpecificRequest();
} int main(int argc,char* argv[])
{
Target * adt = new Adapter(); adt->Request(); return ;
}

对象模式的 Adapter

#include<iostream>

using namespace std;

class Target
{
public:
Target();
virtual ~Target();
virtual void Request();
protected:
private:
};
class Adaptee
{
public:
Adaptee();
~Adaptee();
void SpecificRequest();
protected:
private:
};
class Adapter:public Target
{
public:
Adapter(Adaptee* ade);
~Adapter();
void Request();
protected:
private:
Adaptee* _ade;
};
Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
std::cout<<"Target::Request"<<std::endl;
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<
std::endl;
}
Adapter::Adapter(Adaptee* ade)
{
this->_ade = ade;
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
_ade->SpecificRequest();
} int main(int argc,char* argv[])
{
Adaptee* ade = new Adaptee; Target* adt = new Adapter(ade); adt->Request(); return ;
}

说明
Adapter 模式实现上比较简单,要说明的是在类模式 Adapter 中,我们通过 private 继承Adaptee 获得实现继承的效果,而通过 public 继承 Target 获得接口继承的效果(有关实现继承和接口继承参见讨论部分)。
„ 讨论
在 Adapter 模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接口)。在 C++中的 public 继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过 private 继承获得实现继承的效果(private 继承后,父类中的接口都变为 private,当然只能是实现继承了。),通过纯抽象基类模拟接口继承的效果,但是在 C++中 pure virtual function 也可以提供默认实现,因此这是不纯正的接口继承,但是在 Java 中我们可以 interface 来获得真正的接口继承了。

一个对象模Adpater的例子:

DP上的定义:适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。它包括类适配器和对象适配器,本文针对的是对象适配器。举个例子,在STL中就用到了适配器模式。STL实现了一种数据结构,称为双端队列(deque),支持前后两段的插入与删除。STL实现栈和队列时,没有从头开始定义它们,而是直接使用双端队列实现的。这里双端队列就扮演了适配器的角色。队列用到了它的后端插入,前端删除。而栈用到了它的后端插入,后端删除。假设栈和队列都是一种顺序容器,有两种操作:压入和弹出。下面给出相应的UML图,与DP上的图差不多。

根据上面的UML图,很容易给出实现。

//双端队列
class Deque
{
public:
void push_back(int x) { cout<<"Deque push_back"<<endl; }
void push_front(int x) { cout<<"Deque push_front"<<endl; }
void pop_back() { cout<<"Deque pop_back"<<endl; }
void pop_front() { cout<<"Deque pop_front"<<endl; }
};
//顺序容器
class Sequence
{
public:
virtual void push(int x) = ;
virtual void pop() = ;
};
//栈
class Stack: public Sequence
{
public:
void push(int x) { deque.push_back(x); }
void pop() { deque.pop_back(); }
private:
Deque deque; //双端队列
};
//队列
class Queue: public Sequence
{
public:
void push(int x) { deque.push_back(x); }
void pop() { deque.pop_front(); }
private:
Deque deque; //双端队列
};
int main()
{
Sequence *s1 = new Stack();
Sequence *s2 = new Queue();
s1->push(); s1->pop();
s2->push(); s2->pop();
delete s1; delete s2;
return ;
}

[设计模式] 7 适配器模式 adapter的更多相关文章

  1. 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)

    原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...

  2. 8.3 GOF设计模式二: 适配器模式 Adapter

    GOF设计模式二: 适配器模式 Adapter  为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式  SingleTon的三个关键点  ...

  3. 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)

    怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...

  4. 二十四种设计模式:适配器模式(Adapter Pattern)

    适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.示例有一个Message实体类 ...

  5. 【设计模式】适配器模式 Adapter Pattern

    适配器模式在软件开发界使用及其广泛,在工业界,现实中也是屡见不鲜.比如手机充电器,笔记本充电器,广播接收器,电视接收器等等.都是适配器. 适配器主要作用是让本来不兼容的两个事物兼容和谐的一起工作.比如 ...

  6. Java设计模式之适配器模式(Adapter)

    转载:<JAVA与模式>之适配器模式 这个总结的挺好的,为了加深印象,我自己再尝试总结一下 1.定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法 ...

  7. JavaScript设计模式 Item9 --适配器模式Adapter

    适配器模式(转换器面模式),通常是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况. 适配器模式的作用是解决两个软件实体间的接口不兼容的问题. 一.定义 适配器模式(Adap ...

  8. python 设计模式之适配器模式 Adapter Class/Object Pattern

    #写在前面 看完了<妙味>和<华医>,又情不自禁的找小说看,点开了推荐里面随机弹出的<暗恋.橘生淮南>,翻了下里面的评论,有个读者从里面摘了一段自己很喜欢的话出来, ...

  9. java设计模式之六适配器模式(Adapter)

    适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式.首先,我们来看看类的适配器模 ...

随机推荐

  1. C++ 重载new和delete操作符

    原因: C++标准库提供的new和delete操作符,是一个通用实现,未针对具体对象做具体分析 存在分配器速度慢.小型对象空间浪费严重等问题,不适用于对效率和内存有限制的应用场景   好处: 灵活的内 ...

  2. fluent nhibernate 初体验

    离开.net框架两年时间,发展的很快呀.原先自我感觉良好到以为只差一个MVP的考核什么的,现在觉得真的差好远了. 呵呵,废话就不多说了.这次花了两天时间才拿下fluent nhibernate的fir ...

  3. Linux C 程序 线程(18)

    线程控制 1.线程与进程的关系 线程:计算机中独立运行的最小单位. 在用户角度:多个线程是同时执行的. 操作系统角度:各个线程交替执行 以上只针对单核CPU的情况 在多核CPU主机上,多个线程可以同时 ...

  4. 【Qt】QSettings读写注册表、配置文件【转】

    简述 一般情况下,我们在开发软件过程中,都会缓存一些信息到本地,可以使用轻量级数据库sqlite,也可以操作注册表.读写配置文件. 关于QSettings的使用前面已经介绍过了,比较详细,见“更多参考 ...

  5. [转]浅析AD Exchange——RTB模式

    在上一篇文章中,我们了解了程序化购买,并且知道程序化购买的最基本的一种RTB的竞价模式,了解了DSP.SSP.Ad Exchange等概念,不清楚的同学可以看看上一篇文章<程序化购买>. ...

  6. php实现input输入框失去焦点自动保存输入框的数据

    最近做一个输入框失去焦点时自动保存数据的功能,当然就是jQuery选择器选择input,blur时,ajax提交数据给php文件,php文件保存一下数据咯.主要是要注意一下中文的问题,所以中间需要转一 ...

  7. Android little error records

    1:在清单文件(Manifest)中加入权限时要注意,如下例: <uses-permission android:name="android.permission.CHANGE_NET ...

  8. Microsoft Azure Powershell 获取Azure-Location

    首先要切换至AzureResourceManager模式下 http://www.cnblogs.com/SignalTips/p/4110790.html 国际版Get-AzureLocation ...

  9. mysqldump 参数说明

    mysqldump参数说明 --all-databases , -A 导出全部数据库. mysqldump -uroot -p --all-databases --all-tablespaces , ...

  10. Entity Framework (二) 查询

    待完善-------------------------------------- ----------- base 关键字用于从派生类中访问基类的成员: 调用基类上已被其他方法重写的方法. 指定创建 ...