设计模式 笔记 适配器模式 Adapter
//---------------------------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的更多相关文章
- 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...
- 8.3 GOF设计模式二: 适配器模式 Adapter
GOF设计模式二: 适配器模式 Adapter 为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式 SingleTon的三个关键点 ...
- 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)
怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...
- 二十四种设计模式:适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.示例有一个Message实体类 ...
- 【设计模式】适配器模式 Adapter Pattern
适配器模式在软件开发界使用及其广泛,在工业界,现实中也是屡见不鲜.比如手机充电器,笔记本充电器,广播接收器,电视接收器等等.都是适配器. 适配器主要作用是让本来不兼容的两个事物兼容和谐的一起工作.比如 ...
- Java设计模式之适配器模式(Adapter)
转载:<JAVA与模式>之适配器模式 这个总结的挺好的,为了加深印象,我自己再尝试总结一下 1.定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法 ...
- JavaScript设计模式 Item9 --适配器模式Adapter
适配器模式(转换器面模式),通常是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况. 适配器模式的作用是解决两个软件实体间的接口不兼容的问题. 一.定义 适配器模式(Adap ...
- python 设计模式之适配器模式 Adapter Class/Object Pattern
#写在前面 看完了<妙味>和<华医>,又情不自禁的找小说看,点开了推荐里面随机弹出的<暗恋.橘生淮南>,翻了下里面的评论,有个读者从里面摘了一段自己很喜欢的话出来, ...
- [设计模式] 7 适配器模式 adapter
在 Adapter 模式的结构图中可以看到,类模式的 Adapter 采用继承的方式复用 Adaptee的接口,而在对象模式的 Adapter 中我们则采用组合的方式实现 Adaptee 的复用 类模 ...
随机推荐
- time模块案例演示
案例01: 2008年8月8日20:08:08 往后88,888,888秒是哪天?星期几? 日期->时间戳(浮点数)->可以做数学运算 演示: import time # 构造日期的元组, ...
- 陈远波(java)--Git 入门
本章节讲解思路:1.在Git hup官网注册一个Git账号:2.下载git bash管理工具 3.在git bash上绑定GitHup账号密码: 一:进入GitHup官网:https://githu ...
- python闭包,看不懂请揍我
什么是闭包? 闭包就是一个个内嵌函数+内嵌函数里面引用了外部变量+返回这个内嵌函数(一般是这样) 为什么使用闭包? 有点类似与函数模板?.. 举一个实际的例子: class people: name ...
- Nescafe #29 NOIP模拟赛
Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...
- android studio 错误: InnerClass annotations are missing corresponding EnclosingMember annotations. Such InnerClass annotations are ignored
android studio 错误: InnerClass annotations are missing corresponding EnclosingMember annotations. Suc ...
- screen命令使用
screen -S + name:创建一个名字叫做name的会话.在里面执行你想要执行的程序,再用Ctrl+a+d退出,让会话Detached,这样就能保证你的任务在后台一直运行,也不会随着终端的关闭 ...
- 使用sysbench 进行msyql oltp压力测试
安装参考: https://github.com/akopytov/sysbench#linux#参数说明 需要说明的选项: mysql-db=dbtest1a:测试使用的目标数据库,这个库名要事先创 ...
- 利用存储过程来重命名SQL Server数据库
最近遇到一个需要在多用户模式下重新命名数据库的Case, 因为数据库可能被其他用户使用,所以直接修改可能会失败.对于此种情况,我们可以等所有用户结束使用数据库时修改,或者是将数据库切换到单用户模式下进 ...
- JS省市区联动
JS省市区使用文档 一:服务器返回JSON格式要求如下网址里面data的格式:(拿KISSY组件data格式来做的) http://gallery.kissyui.com/cityselector/d ...
- Android动态的全屏和退出全屏
转自:http://chroya.iteye.com/blog/974031 让程序全屏的方法,大家都知道,那是静态的,程序运行之初就申明了.但是如果有这样的需求:要在程序运行的过程中,执行了某个操作 ...