【设计模式 - 5】之适配器模式(Adapter)
1、模式简介
适配器模式解决的问题:
让原本因为接口不兼容而不能一起工作的类可以一起工作。
适配器模式的UML原理图如下图所示:
从上图可见,客户想要用Target接口实现Adaptee接口中的方法,但这显然是不可能的。因此,我们需要定义一个适配器类Adapter,让它在Target和Adaptee之间做一个“调停者”,进而达到Target和Adaptee的适配。
适配器模式中有三种角色:
- 目标接口Target:用户期望使用的接口,这个类可以是接口,也可以是抽象类或具体类;
- 需要适配的类Adaptee:当前系统中有的类;
- 适配器Adapter:在现有接口和目标接口之间的“调停者”,作用是将现有接口转换成目标接口。
适配器模式的优点:
- 通过适配器模式,用户在做相似的操作时可以调用同一个接口,其内部过程对于用户是透明的,这样做更简单、更直接、更解耦;
- 复用了现存的类,解决了现存类和复用环境要求不一致的问题;
- 将目标接口和现有接口解耦,通过引入一个适配器类,而无需修改原有的代码。
适配器模式的缺点:
使用适配器模式后,如果想要改变适配对象,就需要更换适配器,而更换适配器是一个非常复杂的过程。
适配器模式的适用场景:
- 当系统需要使用现有的类,而现有的类不符合系统的接口的时候;
- 当期望的功能和系统中现有的某个类的功能相似,但是具有不同的接口的时候;
- 当系统已经实现了某个功能,但用户想要通过另一种接口方式访问,而我们不想修改原有接口的时候;
- 当使用的第三方组件的接口和系统中定义好的接口不同,但又不希望修改系统接口的时候。
2、代码
适配器模式有两种实现形式:类适配模式和对象适配模式。下面通过一个实例分别介绍这两种模式。
需求:
我们现在的系统中有一个现有的类Adaptee,这个类中有一个adapteeMethod()方法。但是用户不想用Adaptee这个累,他们想用一个他们自己提供的接口Target,这个接口中有一个targetMethod()方法。虽然这两个类的功能相同,但是Target毕竟是一个接口,我们无法直接调用Adaptee类中的方法,而且我们也不想再把我们千辛万苦写好的Adaptee类中的代码重新写一遍。我们该怎么办?
在解决上面的问题之前,我们先给出Adaptee和Target中的代码:
Adaptee类中的代码:
public class Adaptee {
public void adapteeMethod() {
System.out.println("这是我们已经实现的功能!");
}
}
Target接口中的代码:
public interface Target {
void targetMethod();
}
接下来,我们分别用类适配模式和对象适配模式定义Adapter适配器类,来解决上面的问题。
2.1、类适配模式
首先来看类适配模式的UML图:
可以看到,类适配模式是将Adapter类直接继承Adaptee,这样就直接具有了Adaptee中的adapteeMethod()方法,然后直接在Adapter中实现的Target的targetMethod()方法中调用父类的方法即可达到适配效果。
Adapter类中的代码如下:
public class Adapter extends Adaptee implements Target {
@Override
public void targetMethod() {
super.adapteeMethod();
}
}
测试代码如下:
public class Test {
public static void main(String[] args) {
Targettarget = new Adapter();
target.targetMethod();
}
}
运行结果如下图所示:
2.2、对象适配模式
同理,先来看对象适配模式的UML图:
可以看到,Adapter不再继承Adaptee,而是持有一个Adaptee类的引用,即将一个Adaptee的对象引用到Adapter类中,这就是对象适配模式的思路。同样,在Adapter的targetMethod()方法中调用Adaptee对象的adapteeMethod()方法即可完成适配。
Adapter类中的代码如下:
public class Adapter implements Target {
private Adaptee adaptee = new Adaptee();
@Override
public void targetMethod() {
adaptee.adapteeMethod();
}
}
测试代码与类适配模式的测试代码完全相同。运行结果如下图所示:
以上就是对适配器模式AdapterPattern的介绍。
最后贴出适配器模式的GitHub代码:【GitHub - Adapter】。
【设计模式 - 5】之适配器模式(Adapter)的更多相关文章
- 设计模式 结构型 - 适配器模式 Adapter
Adapter(适配器模式) ---- 加个“适配器”以便于复用 将一个类的接口转换成客户希望的另一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 应用场景 如果 ...
- 设计模式系列之适配器模式(Adapter Pattern)——不兼容结构的协调
模式概述 模式定义 模式结构图 模式伪代码 类适配器,双向适配器,缺省适配器 类适配器 双向适配器 缺省适配器 模式应用 模式在JDK中的应用 模式在开源项目中的应用 模式总结 主要优点 主要缺点 适 ...
- IOS设计模式浅析之适配器模式(Adapter)
引言 在项目开发中,有时候会遇到这样的一种情景:需要使用以前开发的“一些现存的对象”,但是新环境中要求的接口是这些现存对象所不满足的.怎样应对这种迁移的需求?使得可以复用这些对象,以满足新的应用环境, ...
- 《JAVA设计模式》之适配器模式(Adapter)
在阎宏博士的<JAVA与模式>一书中开头是这样描述适配器(Adapter)模式的: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能 ...
- 设计模式(五)适配器模式Adapter(结构型)
设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...
- 乐在其中设计模式(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) 具体解释
适配器模式(adapter pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 适配器模式(adapter pattern): 将一个类的接 ...
随机推荐
- Windows phone 之Xml操作
最近在做天气预报应用,这个应用中需要用到Xml来存储关注的城市列表,保存一下代码,方便以后使用,也给博友们一个参考: 其中:添加关注城市的操作代码是: 其实就是, (1)先把数据从CareCityCo ...
- 超链接字体颜色设置(通过html/css的设置方法)
超链接字体颜色设置是通过css来设置,a链接的颜色设置常用的有以下两种,1.超链接a的初始状态颜色,2.超链接字体的鼠标滑过颜色,还有两种病不常用:3.超链接字体的已访问颜色,4.超链接字体在按下鼠标 ...
- 桂电在线_微信公众平台开发之-运用angularjs显示学校公告新闻列表和详情页面
折腾angularjs的感悟 几天折腾,总的来说看了很多博客,要么不是最新的技术文档,要么写得不够完整,因为别人是基于他们的理解写的技术博客代码不一定会贴完整,所以一旦你用的是最新的想要看完整的实例就 ...
- Android新建项目 默认布局改为 LinearLayout
目前此方法仅适用于eclipse 需要修改SDK 目录 android-sdk/tools/templates/activities/BlankActivity/root/res/layout 文件: ...
- iOS: 学习笔记, 添加一个带界面约束的控制器
1. 创建一个空iOS应用程序(Empty Application). 2. 添加加控制器类. 修改控制器类的viewDidLoad - (void)viewDidLoad { [super view ...
- 4542: [Hnoi2016]大数
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345.小B还有一个素数P.现在,小 B 提出了 M 个询问,每个 ...
- Zoj 3865 Superbot
按规则移动机器人 , 问是否能拾得宝藏 . 加了一个控制板 , 还增加了一个控制板移动周期 p 将移动周期变换一下 , 移动一次 就相当于光标向左不耗费时间的移动了一格 搜索思路 : 搜索当前格子到 ...
- jQuery的preventDefault()
1. 含义: preventDefault() 方法阻止元素发生默认的行为(例如,当点击提交按钮时阻止对表单的提交). 2. 语法: event.preventDefault() 3. 例子: 防止链 ...
- 利用IKVM在C#中调Java程序
原文转自:http://luanxiyuan.iteye.com/blog/1937081 IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java ...
- Bluetooth LE(低功耗蓝牙) - 第一部分
前言 在写这篇文章的时候,谷歌刚刚发布了Android Wear ,摩托罗拉也发布了 Moto 360 智能手表.Android Wear的API还是相当基本的,是很好的文档材料,而且还会不断的更新, ...