设计模式之适配器模式(Adapter)
1. 概述
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
2. 解决的问题
即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
下面是两个非常形象的例子
3. 模式中的角色
3.1 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
3.2 需要适配的类(Adaptee):需要适配的类或适配者类。
3.3 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。
4. 实现方式
(1)类的适配器模式(采用继承实现)
(2)对象适配器(采用对象组合方式实现)
适配器模式的类图
一。类的适配器模式
- // 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
- class Adaptee {
- public void specificRequest() {
- System.out.println("被适配类具有 特殊功能...");
- }
- }
- // 目标接口,或称为标准接口
- interface Target {
- public void request();
- }
- // 具体目标类,只提供普通功能
- class ConcreteTarget implements Target {
- public void request() {
- System.out.println("普通类 具有 普通功能...");
- }
- }
- // 适配器类,继承了被适配类,同时实现标准接口
- class Adapter extends Adaptee implements Target{
- public void request() {
- super.specificRequest();
- }
- }
- // 测试类public class Client {
- public static void main(String[] args) {
- // 使用普通功能类
- Target concreteTarget = new ConcreteTarget();
- concreteTarget.request();
- // 使用特殊功能类,即适配类
- Target adapter = new Adapter();
- adapter.request();
- }
- }

// 已存在的、具有特殊功能、但不符合我们既有的标准接口的类
class Adaptee {
public void specificRequest() {
System.out.println("被适配类具有 特殊功能...");
}
} // 目标接口,或称为标准接口
interface Target {
public void request();
} // 具体目标类,只提供普通功能
class ConcreteTarget implements Target {
public void request() {
System.out.println("普通类 具有 普通功能...");
}
} // 适配器类,继承了被适配类,同时实现标准接口
class Adapter extends Adaptee implements Target{
public void request() {
super.specificRequest();
}
} // 测试类public class Client {
public static void main(String[] args) {
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();
concreteTarget.request(); // 使用特殊功能类,即适配类
Target adapter = new Adapter();
adapter.request();
}
}
测试结果:
- 普通类 具有 普通功能...
- 被适配类具有 特殊功能...

普通类 具有 普通功能...
被适配类具有 特殊功能...
上面这种实现的适配器称为类适配器,因为 Adapter 类既继承了 Adaptee (被适配类),也实现了 Target 接口(因为 Java 不支持多继承,所以这样来实现),在 Client 类中我们可以根据需要选择并创建任一种符合需求的子类,来实现具体功能。另外一种适配器模式是对象适配器,它不是使用多继承或继承再实现的方式,而是使用直接关联,或者称为委托的方式,类图如下:
代码如下:
- // 适配器类,直接关联被适配类,同时实现标准接口
- class Adapter implements Target{
- // 直接关联被适配类
- private Adaptee adaptee;
- // 可以通过构造函数传入具体需要适配的被适配类对象
- public Adapter (Adaptee adaptee) {
- this.adaptee = adaptee;
- }
- public void request() {
- // 这里是使用委托的方式完成特殊功能
- this.adaptee.specificRequest();
- }
- }
- // 测试类
- public class Client {
- public static void main(String[] args) {
- // 使用普通功能类
- Target concreteTarget = new ConcreteTarget();
- concreteTarget.request();
- // 使用特殊功能类,即适配类,
- // 需要先创建一个被适配类的对象作为参数
- Target adapter = new Adapter(new Adaptee());
- adapter.request();
- }
- }

// 适配器类,直接关联被适配类,同时实现标准接口
class Adapter implements Target{
// 直接关联被适配类
private Adaptee adaptee; // 可以通过构造函数传入具体需要适配的被适配类对象
public Adapter (Adaptee adaptee) {
this.adaptee = adaptee;
} public void request() {
// 这里是使用委托的方式完成特殊功能
this.adaptee.specificRequest();
}
} // 测试类
public class Client {
public static void main(String[] args) {
// 使用普通功能类
Target concreteTarget = new ConcreteTarget();
concreteTarget.request(); // 使用特殊功能类,即适配类,
// 需要先创建一个被适配类的对象作为参数
Target adapter = new Adapter(new Adaptee());
adapter.request();
}
}
测试结果与上面的一致。从类图中我们也知道需要修改的只不过就是 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。
5. 模式总结
5.1 优点
5.1.1 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。
5.1.2 复用了现存的类,解决了现存类和复用环境要求不一致的问题。
5.1.3 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
5.1.4 一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。
5.2 缺点
对于对象适配器来说,更换适配器的实现过程比较复杂。
5.3 适用场景
5.3.1 系统需要使用现有的类,而这些类的接口不符合系统的接口。
5.3.2 想要建立一个可以重用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
5.3.3 两个类所做的事情相同或相似,但是具有不同接口的时候。
5.3.4 旧的系统开发的类已经实现了一些功能,但是客户端却只能以另外接口的形式访问,但我们不希望手动更改原有类的时候。
5.3.5 使用第三方组件,组件接口定义和自己定义的不同,不希望修改自己的接口,但是要使用第三方组件接口的功能。
6. 适配器应用举例
6.1 使用过ADO.NET的开发人员应该都用过DataAdapter,它就是用作DataSet和数据源之间的适配器。DataAdapter通过映射Fill和Update来提供这一适配器。
6.2 手机电源适配器
设计模式之适配器模式(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 的复用 类模 ...
- java设计模式之六适配器模式(Adapter)
适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题.主要分为三类:类的适配器模式.对象的适配器模式.接口的适配器模式.首先,我们来看看类的适配器模 ...
随机推荐
- C++_类和动态内存分配4-有关返回对象的说明
返回方式: 返回指向对象的引用: 指向对象的const引用: const对象: =============================================== 返回指向const对象 ...
- Python-list()之remove()/pop() I /del()
代码块 remove #remove删除首个符合条件的元素,并不删除特定的索引. n =[1,2,2,3,4,5] n.remove(3) print (n) #输出 [1, 2, 2, 4, 5] ...
- vue指令与事件修饰符
一.条件渲染指令 vue中提供了两个指令可以用于判断是否要显示元素,分别是v-if和v-show. 实例: <!DOCTYPE html> <html lang="en&q ...
- mysql PXC集群方案总结
同时写集群内的所有机器 写性能依赖最慢的那个机器 读性能提高X倍
- 2.4 GO Interface
package itface type Sender interface { Send(url string) string } type Geter interface { Get(url stri ...
- enum学习
https://www.cnblogs.com/hyl8218/p/5088287.html
- java中构造函数的特点
构造函数的名字必须和类名完全相同,构造函数不能有 返回值,就是void 也不要写,构造函数不可以被子类继承 构造函数可以重载但是不可以被子类覆盖. 简单的例子 class A{ A(){ } A(in ...
- TOJ 2888 Pearls
Description In Pearlania everybody is fond of pearls. One company, called The Royal Pearl, produces ...
- 【Linux】修改ubuntu默认字符集
今天把以前的项目移植到linux上了,我装的是ubuntu,web服务器是tomcat,发现用freemark模板生成的静态页面全 乱码了,在windows都是正常的,猜想可能是linux字符集的问题 ...
- Java网站开发的一些问题以及解决(cookie消失,上传头像,js等)
1.首先是cookie的问题,很多人都是遇到了将数据存储到cookie中并且add到response之中,但是还有返回其他页面或者刷新页面cookie消失的情况,除了设置cookie的存活时间外, 还 ...