说起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. 在Visual Studio 2017中使用Asp.Net Core构建Angular4应用程序

    前言 Visual Studio 2017已经发布了很久了.做为集成了Asp.Net Core 1.1的地表最强IDE工具,越来越受.NET系的开发人员追捧. 随着Google Angular4的发布 ...

  2. JanaScript数据类型

    数据类型 一.基础类型值包括:undefined.null.boolean.string.number 基础类型分别在内存中占有大小空间,它们的值保存在栈空间,我们通过按值来访问. undefined ...

  3. Codeforces Round #418 (Div. 2).C two points

    C. An impassioned circulation of affection time limit per test 2 seconds memory limit per test 256 m ...

  4. 简单的使用Seajs

    什么是Seajs Seajs是一个加载器 http://yslove.net/seajs/ 遵循 CMD 规范模块化开发,依赖的自动加载.配置的简洁清晰. 兼容性 Chrome 3+ Firefox ...

  5. web.xml is missing and <failOnMissingWebXml> is se

    摘要 maven模块化 在学习maven模块化构建项目的时候遇到了如下报错信息: web.xml is missing and <failOnMissingWebXml> is set t ...

  6. 有关各个版本的Visual Studio(VS)和SQL Server安装的顺序总结

    前几天从网上买了块三星的SSD,把原来的HDD放在了光驱位,然后重新安装了系统.想起来收集储存的好多源代码还是VS2008开发的,然后打算把之前用过的VS2008也装上,安装过程出了点问题.发现安装完 ...

  7. angular JS中使用jquery datatable添加checkbox点击事件

    'use strict'; app.controller('DataTableCtrl', function ($scope, $compile) { $scope.selected = []; $s ...

  8. dubbo-zookeeper(续)

    本篇为继上一篇的续篇,主要内容分为以下几点: 1.zookeeper集群 2.web管理平台 3.dubbo配置说明 接下来我们开始继续吧. 一.zookeeper集群 顾名思义也就是多台zookee ...

  9. Jenkins发布MVC应用程序

    一个大的项目一般都会进行模块化.层次化分隔,每个模块.每个层次都可能是一个或多个工程文件组成,而且各个模块都有依赖关系,有先后顺序,先build哪个然后再build哪个都是有顺序的,如果想build一 ...

  10. R语言 write.xlsx() 写入同一excel,及同一sheet注意

    write.xlsx(x, file, sheetName="Sheet1", col.names=TRUE, row.names=TRUE, append=FALSE, show ...