设计模式面面观(9):适配器模式(Adapter Pattern)-结构型模式

适配器模式(Adapter-结构型模式

适配器模式,对刚刚接触设计模式的朋友来说是一个即陌生有熟悉的模式,听起来很矛盾对吧,在我们的编程中很多时候我们都用到了这个模式,但您也许没有想起来,等我们学习完后你会惊奇的说声:啊!原来我一直在用这个模式啊。其实在我们生活中处处都有这种模式的存在,小到一个手机的万能充电器(不要告诉我你没见过这玩意)都存在这一个原则,在不破坏或更改原有实体的前提下,利用原有实体的特性(方法)定制一个新实体来达到用户需要的效果。听起来没头没脑的呵呵!让我们看看他的结构就恍然大悟了

设计模式面面观(9):适配器模式(Adapter Pattern)-结构型模式

<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 125.25pt" type="#_x0000_t75" o:ole=""><imagedata src="file:///C:%5CDOCUME~1%5CWensi%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.emz" o:title=""></imagedata></shape>

用户的需求是千变万化的,他们可能要给MOTO手机充电也可能会给诺基亚手机或者其他的手机充电,但每个手机肯定有充电的接口,所以这里定义了一个抽现的手机类,万能充电器继承了抽现手机类,也继承了万能充电器的接口,这样不管什么手机,只要他提供充电接口,万能充电器总是可以帮他充电。这种适配叫做类适配模式。

这个是生活中的一个小例子,那在我们回到现实开发中来,很多朋友肯定遇到过这样的情况,自己原先积累的一些自己的类库,在项目开发中时项目经理告诉你他提供喽一个接口告诉你需要实现什么功能,你发现这个功能和你类库中的某个类提供的功能是基本符合的,但接口的名字不一样,这时你需要建一个类这个类成员中存放自己类库中的类,继承并实现项目经理给的接口。这个就是结构型适配器。这个和我上面将的类适配不同点是把原有的类实体一个是直接继承,一个是当作类成员。2者有区别吗?那是当然有了。

类适配:是正对单一的类型做的适配。

结构适配:是对多类型实体实现一个接口方法。

看到这里你是否明白了适配器模式了呢,是否惊奇的发现原来你一直在用这个模式了呢。

让我们回头看看这个OOD设计是否合理,我们依据我们第二章的设计模式原则来判定

1. 是否符合开闭原则

我们对原有手机的充电接口没有做任何改变,在外面添加一个适配器类做对应方法。

答案:符合

2. 是否符合里氏代换原则

万能充电器继承的是手机抽象类,如果他继承的是MOTO手机或是诺基亚手机类都是可以的。

答案:符合

3. 是否符合依赖倒置原则

万能充电器类对抽象手机的依赖和对充电接口的依赖

答案:符合

4. 是否符合接口隔离原则

答案:符合

5. 是否符合抽象原则

答案:符合

6. 是否符合迪米特法则

答案:符合

总结 :原型模式

意图

将一个类的接口转换成另一个类客户希望的另一个接口。Adapter模式使得原本由接口不兼容而不能一起工作的那些类可以一起工作

动机

为了复用原有的类完成客户希望通过不同的接口完成的任务。

实用性

l 用户自定义类的复用

l 在原有自定义类上进行扩展,达到客户需要的效果和指定的接口

适用性

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

l 创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。

l 使用一些已经存在的子类,但不可能对每个都进行子类化以配置他们的接口。对象适配器可以适配它的父类接口(仅适用于对象Adapter

结构

<shape id="_x0000_i1026" style="WIDTH: 407.25pt; HEIGHT: 147.75pt" type="#_x0000_t75" alt=""><imagedata src="file:///C:%5CDOCUME~1%5CWensi%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.gif" o:href="http://www.cnblogs.com/images/cnblogs_com/zhenyulu/Pic57.gif"><font size="3"></font></imagedata></shape>

设计模式面面观(9):适配器模式(Adapter Pattern)-结构型模式

参与者

l Target (万能充电器接口)

l Adapter (万能充电器)

l Adaptee (品牌充电器 摩托罗拉充电器,诺基亚充电器)

注意

区分类适配器和对象适配器

1. 类适配器

l 用一个具体的Adapter类对AdapteeTarget进行匹配。结果是当我们想要匹配一个类以及所有他的子类时,类Adapter将不能胜任工作。

l Adapter可以重定义Adaptee的部分行为,因为AdapterAdaptee的一个子类

l 仅仅引入了一个对象并不需要额外的指针以间接等到adaptee.

2. 对象适配器

l 允许一个Adapter也多个Adaptee同时工作,Adapter也可以一次给所有的Adaptee添加功能

l 重定义Adaptee的行为比较困难。这就需要生成Adaptee的子类兵器使得Adapter引用这个子类而不是引用Adaptee本身。

代码

http://download.csdn.net/source/316287

你可能感兴趣的:(设计模式,编程,生活,F#,ext)