最新消息:

适配器(Adapter)模式

JAVA 大步 195浏览 0评论

适配器(Adapter)模式

在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。那么如何应对这种“迁移变化”?如果既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?这就是Adapter模式的作用。
GoF定义:将接口的一个类转换成另一个客户端所期望的接口。适配器模式使得类不会由于接口的兼容性而影响它们一起工作。

现实生活中的例子

如移动充电设备。如果我们的充电器不支持某个特定的接口,我们就需要使用一个适配器。

计算式世界中的例子

在现实世界的开发中,很多情况下,我们不能让两个接口直接通信。它们各自包含在自己的某些约束中。为了解决两个接口之间的兼容性,我们就需要引入适配器。

适配器模式的构成

目标抽象角色(Target)
- 定义客户要用的特定领域的接口
适配器(Adapter)
- 调用另一个接口,作为转换器
适配器(Adaptee)
- 定义一个接口,Adapter需要接入
客户端(Client)
- 协同对象符合Adapter适配器

适配器的分类

GoF告诉我们适配器有两种类型:
  1. 类适配器(Class adapter)。采用继承的方式。它们同时使用多个继承来将一个接口适配到另外一个接口。(但是,我们必须记住,在java里,多继承是不支持的。所以,我们需要多个接口来实现多继承)
  2. 对象适配器(Object adapter):采用对象组合的方式。它们依赖于这个对象的组成。推荐这种

适用性

对象需要利用现存的并且接口不兼容的类
需要创建可重用的类以协调其他接口可能的不兼容

实例1:使用对象适配器

假设,我们可以直接计算长方形的面积。
在Calculator类中有getArea()方法,其参数是Rect(长方形)对象。如果此时,我们想让Calculator的getArea()方法计算三角形的面积,显然是无法实现的,那怎么办呢?
这时候就可以使用一个适配器,适配器内部将这个三角形转换为一个Rect类,然后调用Calculator的getArea()方法即可,这样就无需修改原有的代码了。
UML图:
长方形类:
三角形类:
用来计算长方形的面积的类:
适配器:将三角形面积的计算转换为长方形计算方式
客户端:
结果:
***Adapter Pattern Demo***
Adapter Pattern Example
Area of Triangle is :100.0

实例2:类适配器与对象适配器的对比

下面对于一个实现,同时使用类适配器和对象适配器。
目标:对原来的值进行 +2操作。
UML

 接口:
接口的实现类:
类适配器:
对象适配器:
客户端:
结果:
***Class and Object Adapter Demo***
Class Adapter is returning :7
Object Adapter is returning :7

实例3:类适配器,这个更好说明多继承

UML

接口:
类适配器使用多继承(通过接口实现)
客户端:

优点

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。
  • 增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。
  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
类适配器模式还具有如下优点
由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强。
对象适配器模式还具有如下优点
一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

缺点

当目标接口的与当前的接口相似度较高时,适配器只需要做少量的工作。如果相似度不高,那么适配器可能要做大量的多余的工作来进行适配。
参考:
《java design patterns》
《图说设计模式》

 

来自为知笔记(Wiz)

 

转载请注明:大步's Blog » 适配器(Adapter)模式

SiteMap