说起Adapter,STL里的stack和queue都是adapter,底层是deque,隐藏了deque的一些接口,使得其可以达到FIFO是queue,LIFO是stack。

The STL stack is a container adaptor. That is, it is not a "first-class" container, but instead simply "adapts" one of the sequential first-class containers (by default, the deque) for its own purposes. So, the deque interface is restricted (i.e., much of it is hidden) so that the required LIFO (Last In, First Out) stack-like behavior is provided.

再说通透一点,adapter就是适配器,电源适配器知道吧,把220v交流电转换为笔记本可接受的电压和电流就是我们常见的电源适配器,手机电源适配器等等。

还有STL里本来就有一类叫做adapter,有容器adapter即stack和queue,还有迭代器的adapter,有insert iterators,reverse iterators,iostream iterators,还有仿函数的functor adapters,我印象比较深的仿函数adapter就是,可以给二元操作给一个参数也能用,等等。。STL里都写的比较清楚。这里就不赘述了。

正题:

Adapter适配器模式是将两个不兼容的类组合在一起使用。适配器起到一种转换和包装的作用。

Adapter设计模式主要目的组合两个不相干类,常用有两种方法:第一种解决方案是修改各自类的接口。但是如果没有源码,或者不愿意为了一个应用而修改各自的接口,则需要使用Adapter适配器,在两种接口之间创建一个混合接口。

Adapter适配器设计模式中有3个重要角色:被适配者Adaptee,适配器Adapter和目标对象Target。其中两个现存的想要组合到一起的类分别是被适配者Adaptee和目标对象Target角色,我们需要创建一个适配器Adapter将其组合在一起。

实现Adapter适配器设计模式有两种方式:组合(compositon, has-a关系)和继承(inheritance,is-a关系)。

对象适配器模式使用组合,UML图如下:

利用组合实现的Adapter模式:

就是Aapter里实际上包含一个被适配的对象。(组合)又继承了target。因此如果要用到target的方法,直接调用父类的方法,如果要用到被适配者的方法, 就调用内部成员的函数。

//圆形,目标对象
class Cirecle{
public void drawCircle(){
System.out.println(“Draw circle”);
}
}
//方形,被适配对象
class Square{
public void drawSquare(){
System.out.println(“Draw square”);
}
}
//既可以画圆形,又可以画方形,适配器
public class HybridShape extends Circle{
private Square square;
public HybridShape(Square square){
this.square = square;
}
public void drawSquare(){
square.drawSquare();
}
} interface ICircle{
public void drawCircle();
}
interface ISquare{
public void drawSquare();
}
//圆形
class Cirecle implements ICircle{
public void drawCircle(){
System.out.println(“Draw circle”);
}
}
//方形
class Square implements ISquare{
public void drawSquare(){
System.out.println(“Draw square”);
}
}
//既可以画圆形,又可以画方形,适配器
public class HybridShape implements ICircle, ISquare{
private ISquare square;
private ICircle circle;
public HybridShape(Square square){
this.square = square;
}
public HybridShape(Circle circle){
this.circle = circle;
}
public void drawSquare(){
square.drawSquare();
}
public void drawCircle(){
circle.drawCircle();
}
}

利用多继承方式实现Adapter模式,java里不支持多继承,但是可以用interface实现。

先上类图:

可以看到Adapter同时继承了target和adaptee。

  //目标接口类,客户需要的接口
class Target
{
public:
Target();
virtual ~Target();
virtual void Request();//定义标准接口
}; //需要适配的类
class Adaptee
{
public:
Adaptee();
~Adaptee();
void SpecificRequest();
}; //类模式,适配器类,通过public继承获得接口继承的效果,通过private继承获得实现继承的效果
class Adapter:public Target,private Adaptee
{
public:
Adapter();
~Adapter();
virtual void Request();//实现Target定义的Request接口
}; Target::Target()
{} Target::~Target()
{} void Target::Request()
{
cout << "Target::Request()" << endl;
} Adaptee::Adaptee()
{
} Adaptee::~Adaptee()
{
} void Adaptee::SpecificRequest()
{
cout << "Adaptee::SpecificRequest()" << endl;
} //类模式的Adapter
Adapter::Adapter()
{
} Adapter::~Adapter()
{
} void Adapter::Request()
{
cout << "Adapter::Request()" << endl;
this->SpecificRequest();
cout << "----------------------------" <<endl;
}

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

设计模式之Adapter模式的更多相关文章

  1. 设计模式--适配器(Adapter)模式

    今天学习另一个设计模式,适配器(Adapter)模式,这是一个共同方向,但有特殊要求,就应用到此设计模式.写到这里,想起很久以前,有写过一篇<ASP.NET的适配器设计模式(Adapter)&g ...

  2. 设计模式:Adapter模式

    目的:复用代码和兼容以前的代码 思想:提供一个中间层,做兼容 方法:“继承”的方式,“委托”的方式 继承关系图: 委托方式 继承方式 例子: //原来的打印 class Print { public: ...

  3. 2、适配器 adapter 模式 加个"适配器" 以便于复用 结构型设计模式

    1.什么是适配器模式? 适配器如同一个常见的变压器,也如同电脑的变压器和插线板之间的电源连接线,他们虽然都是3相的,但是电脑后面的插孔却不能直接插到插线板上. 如果想让额定工作电压是直流12伏特的笔记 ...

  4. java设计模式—Adapter模式

    1.核心意图:     将一个类的接口转换成客户希望的另外一个接口,从而使得原本由于接口不兼容而不能一起工作的类可以一起工作. 该模式的目标是通过一个代理(这里是Adapter),在原来的类(Adap ...

  5. 设计模式---接口隔离模式之适配器模式(Adapter)

    一:概念 通过Adapter模式可以改变已有类(或外部类)的接口形式 二:动机 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不 ...

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

    适配器模式定义:将两个不兼容的类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adaptor(适配器)两个身份. 为何使用适配器模式 我们经常碰到要将两个没有关系的类组合在一起使用 ...

  7. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

  8. 设计模式(二)Adapter模式

    Adapter模式也被成为Wrapper模式.适配器模式用于填补“现有的程序”和“所需的程序”之间差异的设计模式. Adapter模式有两种,即使用继承的适配器和使用委托的适配器. 1.使用继承的适配 ...

  9. 设计模式学习笔记-Adapter模式

    Adapter模式,就是适配器模式,使两个原本没有关联的类结合一起使用. 平时我们会经常碰到这样的情况,有了两个现成的类,它们之间没有什么联系,但是我们现在既想用其中一个类的方法,同时也想用另外一个类 ...

随机推荐

  1. servlet+jsp update修改页面的实现,整整搞了两个小时才搞定

    package DAO; public class books { private int bid; private String bname; private int booksl; private ...

  2. 钉钉企业应用C#开发笔记之一(免登)

    关于钉钉 钉钉是阿里推出的企业移动OA平台,本身提供了丰富的通用应用,同时其强大的后台API接入能力让企业接入自主开发的应用成为可能,可以让开发者实现几乎任何需要的功能. 近期因为工作需要研究了一下钉 ...

  3. 百度云bcc建站

    一.购买百度云服务 1.百度云bcc购买网页http://bce.baidu.com/product/bcc.html 2.买完后管理:http://console.bce.baidu.com/bcc ...

  4. (转发)RequestDispatcher的include()方法和forward()方法的区别

    forward(): 该方法用于将请求从一个Servlet传递给服务器上的另外的Servlet.JSP页面或者是HTML文件. 在Servlet中,可以对请求做一个初步的处理,然后调用这个方法,将请求 ...

  5. 前端模块化工具--webpack使用感受

    话说前头 webpack前段时间有听说一下,现在已经到了3.x的版本,自己没去接触.因为之前使用gulp来作为自己的项目构建工具.现在感觉gulp使用的趋势在减少.现在这段时间去接触了webpack, ...

  6. linux shell变量$#,$@,$0,$1,$2的含义解释

    变量说明: $$ Shell本身的PID(ProcessID) $! Shell最后运行的后台Process的PID $? 最后运行的命令的结束代码(返回值) $- 使用Set命令设定的Flag一览  ...

  7. HashMap TreeMap ConcurrentHashMap 源码

    1 HashMap java se 1.6 1.1 父类 java.lang.Object 继承者 java.util.AbstractMap<K,V> 继承者 java.util.Has ...

  8. Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors

    阅读源码有利于陶冶情操,承接前文Spring源码情操陶冶-AbstractApplicationContext#postProcessBeanFactory 约定:web.xml中配置的context ...

  9. 【HTML】section

    1.  定义 标签定义文档中的节(section.区段).比如章节.页眉.页脚或文档中的其他部分. 2. div.section . article的区别 div: 本身没有任何语义,用作布局以及样式 ...

  10. github 发布项目

    自己开发了一个插件或项目,需要发布到github上,之前看到很多文章,但是都会有一些问题,经过自己多次尝试,想分享给初学者们. 首先你需要一个github账号,所有还没有的话先去注册吧! 官网:htt ...