//---------------------------15/04/13----------------------------

//Adapter 适配器模式 ----类对象结构型模式

/*

1:意图:

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容

而不能一起工作的那些类可以一起工作。

2:别名: Wrapper

3:动机

4:适用性:

1>你想使用一个已经存在的类,而它的接口不符合你的需求。

2>你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口

可能不一定兼容的类)协同工作。

3>(仅对象Adapter)你想使用一些已经存在的子类,但是不可能对每一个都进行子类化

以匹配它们的接口。对象适配器可以适配它的父类接口。

5:结构:

1>类适配器:

Client-------->Target:          Adaptee:

Request()        SpecificRequest()

|                     |

-----------------------

|

Adapter:

Request()

{ SpecificRequest() }

2>对象适配器:

Client-------->Target:

Request()

|             ----->Adaptee:

|     adaptee |     SpecificRequest()

Adapter-----------

Request()

{ adaptee->SpecificRequest() }

6:参与者:

1>Target:定义了Client使用的与特定领域相关的接口。

2>Client:与符合Target接口的对象协同。

3>Adaptee:定义了一个已经存在的接口,这个接口需要适配。

4>Adapter:对Adaptee的接口与Target接口进行适配。

7:协作:

Client在Adapter实例上调用一些操作。接着适配器调用Adaptee的操作实现这个请求。

8:效果:

1>类适配器:

1)用一个具体的Adapter类对Adaptee和Target进行匹配。结果是当我们想要匹配一个类

以及所有它的子类时,类Adapter将不能胜任工作。

2)使得Adapter可以重定义Adaptee的部分行为,因为Adapter是Adaptee的一个子类。

3)仅仅引入了一个对象,并不需要额外的指针以间接得到Adaptee。

2>对象适配器:

1)允许一个Adapter与多个Adaptee--即Adaptee本身以及它的所有子类(如果有子类的话)

同时工作。Adapter也可以一次给所有的Adaptee添加功能。

2)使得重定义Adaptee的行为比较困难,这就需要生成Adaptee的子类并且使得Adapter引用

这个子类而不是引用Adaptee本身。

3>需要考虑的其他因素:

1)Adapter的匹配程度。对Adaptee的接口与Target的接口进行匹配的工作量各个Adapter

可能不一样。工作范围可能是,从简单的接口转换(例如改变操作名)到支持完全不同的操作

集合。Adapter的工作量取决于Target接口与Adaptee接口的相似程度。

2)可插入的Adapter。当其他的类使用一个类时,如果所需的假定条件越少,这个类就更具可

复用性。如果将接口匹配构建为一个类,就不需要假定对其他的类可见的是一个相同的接口。

也就是说,接口匹配使得我们可以将自己的类加入到一些现有的系统中去,而这些系统对

这个类的接口可能会有所不同。

3)使用双向适配器提供透明操作。使用适配器的一个潜在问题是,它们不对所有的客户都透明。

被适配的对象不再兼容Adaptee的接口,因此并不是所有Adaptee对象可以被使用的地方它

都可以被使用。双向适配器提供了这样的透明性。在两个不同的客户需要用不同的方式查看

同一个对象时,双向适配器尤其有用。

9:实现:

注意的问题:

1>使用c++实现适配器。在使用c++实现适配器类时,Adapter类应该采用public方式继承Target类

并且用private方式继承Adaptee类。因为Adaptee的接口只是拿来用的,不需要传承下去。

2>可插入的Adapter。
有许多方法可以实现。一共有三种。

1)首先(三种实现都要做的):

为Adaptee找到一个窄接口,即可用于适配的最小操作集。因为包含较少操作的窄接口相对

包含较多操作的宽接口比较容易进行匹配。

2)实现途径:

a):使用抽象操作。窄接口定义相应的抽象操作,由子类来实现这些抽象操作。

b):使用代理对象。在客户类中存放一个代理,并调用代理的抽象方法,Adapter可以实现

抽象方法来达到适配的目的。

c):参数化的适配器。

10:代码示例:                                                                    */

//类适配器:

//Target

class Shape

{

public:

Shape();

virtual void BoundingBox(Point& bottomLeft, Point& topRight)const;

virtual Manipulator* CreateManipulator()
const;

};

//Adaptee

class TextView

{

public:

TextView();

void GetOrigin(Coord& x, Coord& y)
const;

void GetExtent(Coord& width, Coord& height)
const;

virtual bool IsEmpty()
const;

};

//Adapter只需要实现Target的接口,但是要使用Adaptee的接口

class TextShape:
public Shape, private TextView

{

public:

TextShape();

virtual void BoundingBox(Point& bottomLeft, Point& topRight)
const;

virtual bool IsEmpty()
const;

virtual Manipulator* CreateManipulator()
const;

};

//把Coord接口类型为Point类型

void TextShape::BoundingBox(Point& bottomLeft, Point& topRight)
const

{

Coord bottom, left, width, height;

GetOrigin(bottom, left);

GetExtent(width, height);

bottomLeft = Point(bottom, left);

topRight = Point(bottom + height, left + width);

}

bool TextShape::IsEmpty()
const

{

return TextView::IsEmpty();

}

//需要自己实现,Adaptee并没有这功能。

Manipulator* TextShape::CreateManipulator()
const

{

return new TextManipulater(this);

}

//对象适配器,操作几乎完全一样,只需要把相应的从adaptee继承来的操作改成使用

//_text来做的操作

class TextShape :
public Shape

{

public:

TextShape(TextView*);

virtual void BoundingBox(Point& bottomLeft, Point& topRight)
const;

virtual bool IsEmpty()
const;

virtual Manipulator* CreateManipulator()
const;

private:

TextView* _text;

};

TextShape::TextShape(TextView* t)

{

_text = t;

}

void TextShape::BoundingBox(Point& bottomLeft, Point& topRight)
const

{

Coord bottom, left, width, height;

_text->GetOrigin(bottom, left);

_text->GetExtent(width, height);

bottomLeft = Point(bottom, left);

topRight = Point(bottom + height, left + width);

}

Manipulator* TextShape::CreateManipulator()
const

{

return new TextManipulater(this);

}

//虽然对象适配器实现起来稍微复杂了一点,但是更加灵活,可以活用adaptee的子类。

设计模式 笔记 适配器模式 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. [设计模式] 7 适配器模式 adapter

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

随机推荐

  1. CAC的Debian-8-64bit安装BBR正确方式是?

    裝过三台debian 64 bit, CAC, 2歐, KVM虛擬機 做法都一樣 0. 有裝銳速記得先刪除, 免得換核心後, 銳速在扯後腿 1.換4.9版kernel 有正式版 別裝啥rc版, 4.9 ...

  2. Oracle EBS INV 获取现有量等值

    DECLARE L_api_return_status VARCHAR2(1); l_qty_oh NUMBER; l_qty_res_oh NUMBER; l_qty_res NUMBER; l_q ...

  3. 学习笔记:The Best of MySQL Forum

    http://mysql.rjweb.org/bestof.html I have tagged many of the better forum threads. 'Better' is based ...

  4. 在Ubuntu17.04中遇到无法清空回收站解决方法

    在Ubuntu17.04下,遇到清空回收站文件时报错,提示”Failed to delete the item from the trash”,无法清空回收站. 回收站其实就是一个文件夹,存放着被删掉 ...

  5. [转]Java学习---7大经典的排序算法总结实现

    [原文]https://www.toutiao.com/i6591634652274885128/ 常见排序算法总结与实现 本文使用Java实现这几种排序. 以下是对排序算法总体的介绍. 冒泡排序 比 ...

  6. 关于ORA-00257: archiver error. Connect internal only, until freed 错误处理方法

    产生原因:出现ORA-00257错误(空间不足错误),通过查找资料,绝大部分说这是由于归档日志太多,占用了全部的硬盘剩余空间导致的,通过简单删除日志或加大存储空间就能够解决 解决办法:(亲测有效) 1 ...

  7. VS 0x80041FEB

    在打开from设计界面时,报错. 解决方法:将项目中Properties文件中licenses.licx删除,重新建立一个空的licenses.licx文件放到项目中. 重新打开界面,解决

  8. C 语言之预处理 ---------文件包括

    文件包括是C预处理程序的还有一个重要功能. 文件包括命令行的一般形式为: #include"文件名称" 在前面我们已多次用此命令包括过库函数的头文件. 比如: #include&q ...

  9. 【剑指offer】数值的整数次方

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/25506085 转载请注明出处:http:// ...

  10. Spark2.3文档翻阅的一点简略笔记(WaterMarking)

    写本文原因是之前已经将官网文档阅读过几遍,但是后来工作接触spark机会较少所以没有跟进新特性,利用周末一点闲暇时间粗略阅读一篇,将自己之前遇见过的问题解决过的问题印象不深刻的问题做一下记录. 1关于 ...