1、什么是适配器模式?

Convert the interface of a class into another interface clients expect.Adapter lets classes work together that couldn't otherwise because of incompatible interfaces.

适配器模式(Adapter Pattern):将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

说人话:这个模式就是用来做适配的,它将不兼容的接口转换为可兼容的接口,让原本由于接口不兼容而不能一起工作的类可以一起工作。比如现实生活中的例子, USB 转接头就充当适配器,把两种不兼容的接口,通过转接变得可以一起工作。

2、适配器模式定义

①、Target目标角色

该角色定义把其他类转换为何种接口, 也就是我们的期望接口, 例子中的IUserInfo接口就是目标角色。

②、Adaptee源角色

你想把谁转换成目标角色, 这个“谁”就是源角色, 它是已经存在的、 运行良好的类或对象, 经过适配器角色的包装, 它会成为一个崭新、 靓丽的角色。

③、Adapter适配器角色

适配器模式的核心角色, 其他两个角色都是已经存在的角色, 而适配器角色是需要新建立的, 它的职责非常简单: 把源角色转换为目标角色, 怎么转换? 通过继承或是类关联的方式。

3、适配器模式通用代码实现

/**
* 目标角色
*/
public interface Target {
void t1();
void t2();
void t3();
}
/**
* 目标角色实现类
*/
public class ConcreteTarget implements Target{ @Override
public void t1() {
System.out.println("目标角色 t1 方法");
} @Override
public void t2() {
System.out.println("目标角色 t2 方法");
} @Override
public void t3() {
System.out.println("目标角色 t3 方法");
}
}
/**
* 源角色:要把源角色转换成目标角色
*/
public class Adaptee { public void a1(){
System.out.println("源角色 a1 方法");
} public void a2(){
System.out.println("源角色 a2 方法");
} public void a3(){
System.out.println("源角色 a3 方法");
}
}

基于继承的类适配器

/**
* 适配器角色
*/
public class Adapter extends Adaptee implements Target{ @Override
public void t1() {
super.a1();
} @Override
public void t2() {
super.a2();
} @Override
public void t3() {
super.a3();
}
}

基于组合的对象适配器

public class AdapterCompose implements Target{

    private Adaptee adaptee;

    public AdapterCompose(Adaptee adaptee){
this.adaptee = adaptee;
}
@Override
public void t1() {
adaptee.a1();
} @Override
public void t2() {
adaptee.a2();
} @Override
public void t3() {
adaptee.a3();
}
}

测试:

public class AdapterClient {

    public static void main(String[] args) {
// 原有的业务逻辑
Target target = new ConcreteTarget();
target.t1(); // 基于继承 增加适配器业务逻辑
Target target1 = new Adapter();
target1.t1(); // 基于组合 增加适配器业务逻辑
Target target2 = new AdapterCompose(new Adaptee());
target2.t1();
}
}

打印结果:

适配器模式有两种实现方式:类适配器和对象适配器。其中,类适配器使用继承关系来实现,对象适配器使用组合关系来实现。在实际开发中,选择的依据如下:

①、如果 Adaptee 接口并不多,那两种实现方式都可以。

②、如果 Adaptee 接口很多,而且 Adaptee 和 ITarget 接口定义大部分都相同,那我们推荐使用类适配器,因为 Adaptor 复用父类 Adaptee 的接口,比起对象适配器的实现方式,Adaptor 的代码量要少一些。

③、如果 Adaptee 接口很多,而且 Adaptee 和 ITarget 接口定义大部分都不相同,那我们推荐使用对象适配器,因为组合结构相对于继承更加灵活。

4、适配器模式优点

①、适配器模式可以让两个没有任何关系的类在一起运行, 只要适配器这个角色能够搞定他们就成。

②、增加了类的透明性

我们访问的Target目标角色, 但是具体的实现都委托给了源角色, 而这些对高层次模块是透明的, 也是它不需要关心的。

③、提高了类的复用度

源角色在原有的系统中还是可以正常使用, 而在目标角色中也可以充当新的演员。

④、灵活性非常好

适配器可以随时去掉,而不会影响很多代码。

5、适配器模式应用场景

①、修改已使用的接口

某个已经投产中的接口需要修改,这时候使用适配器最好。

②、统一多个类的接口设计

比如对于敏感词过滤,需要调用好几个第三方接口,每个接口方法名,方法参数又不一样,这时候使用适配器模式,将所有第三方的接口适配为统一的接口定义。

③、兼容老版本接口

比如JDK1.0 中包含一个遍历集合容器的类 Enumeration,JDK2.0 对这个类进行了重构,将它改名为 Iterator 类,并且对它的代码实现做了优化。但是考虑到如果将 Enumeration 直接从 JDK2.0 中删除,那使用 JDK1.0 的项目如果切换到 JDK2.0,代码就会编译不通过。为了避免这种情况的发生,我们必须把项目中所有使用到 Enumeration 的地方,都修改为使用 Iterator 才行。

单独一个项目做 Enumeration 到 Iterator 的替换,勉强还能接受。但是,使用 Java 开发的项目太多了,一次 JDK 的升级,导致所有的项目不做代码修改就会编译报错,这显然是不合理的。这就是我们经常所说的不兼容升级。为了做到兼容使用低版本 JDK 的老代码,我们可以暂时保留 Enumeration 类,并将其实现替换为直接调用 Itertor。

public class Collections {
public static Emueration emumeration(final Collection c) {
return new Enumeration() {
Iterator i = c.iterator(); public boolean hasMoreElments() {
return i.hashNext();
} public Object nextElement() {
return i.next():
}
}
}
}

④、适配不同格式的数据

6、代理-桥接-装饰器-适配器区别

①、代理模式在不改变原始类接口的条件下,为原始类定义一个代理类,主要目的是控制访问,而非加强功能,这是它跟装饰器模式最大的不同。

②、桥接模式:桥接模式的目的是将接口部分和实现部分分离,从而让它们可以较为容易、也相对独立地加以改变。

③、装饰器模式:装饰者模式在不改变原始类接口的情况下,对原始类功能进行增强,并且支持多个装饰器的嵌套使用。

④、适配器模式:适配器模式是一种事后的补救策略。适配器提供跟原始类不同的接口,而代理模式、装饰器模式提供的都是跟原始类相同的接口。

Java设计模式之(八)——适配器模式的更多相关文章

  1. 重学 Java 设计模式:实战适配器模式

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 擦屁屁纸80%的面积都是保护手的! 工作到3年左右很大一部分程序员都想提升自己的技术 ...

  2. java设计模式(八) 适配器模式

    [适配器模式]将一个类的接口,转换成客户期望的另外一个接口.适配器让原本接口不兼容的类可以合作无间. 1,Duck接口 package com.pattern.adapter; public inte ...

  3. Java设计模式系列之适配器模式

    适配器模式的定义 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.(就类似于我们充电器的转接头将220V的电压转换成我们的手机端 ...

  4. Java设计模式7:适配器模式

    适配器模式 适配器模式说的是,可以把一个类的接口变换成客户端所期待的另一种接口,使得原本因接口不匹配而无法在一起工作的两个类可以一起工作. 适配器模式的用途 适配器模式的用途,在网上找了一幅图,挺形象 ...

  5. java设计模式笔记(1)-适配器模式

    适配器的定义 适配器就是一个接口转换器,它可以是一个独立的硬件接口设备,允许硬件或电子接口与其它硬件或电子接口相连,也可以是信息接口.比如:电源适配器.三角架基座转接部件.USB与串口的转接设备等. ...

  6. java 设计模式-缺省适配器模式

    本文转载地址:http://www.cnblogs.com/iyangyuan/archive/2013/03/11/2954808.html 在程序设计过程中,读者很可能遇到这样一种困境:设计了一个 ...

  7. java设计模式自我总结---适配器模式

    上一篇博客说完了 java 23 中设计模式中的五种 创建性模式,由于篇幅过长,新开一贴今天开始学习结构型模式, 结构型模式包括以下七种:适配器模式.装饰模式.代理模式.外观模式.桥接模式.组合模式. ...

  8. JAVA设计模式初探之适配器模式

    http://blog.csdn.net/jason0539/article/details/22468457 1. 概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接 ...

  9. Java设计模式学习记录-适配器模式

    前言 之前已经将五个创建型设计模式介绍完了,从这一篇开始介绍结构型设计模式,适配器模式就是结构型模式的一种,适配器要实现的效果是把“源”过渡到“目标”. 适配器模式 在开发过程中,使用一个已经存在的类 ...

  10. JAVA设计模式初探之适配器模式(转)

    1. 概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 解决的问题 即Adapter模式使得原本由于接口不兼容而不 ...

随机推荐

  1. 8.18考试总结[NOIP模拟43]

    又挂了$80$ 好气哦,但要保持优雅.(草 T1 地衣体 小小的贪心:每次肯定从深度较小的点向深度较大的点转移更优. 模拟一下,把边按链接点的子树最大深度排序,发现实际上只有上一个遍历到的点是对当前考 ...

  2. CSP-S 2021 退役记

    写的比较草率,但的确是真实感受. 10.23 回寝室前敲了一个 dinic 板子,觉得不会考... 10.24 8:00 起床,还好今天宿管不在,可以起的晚一点. 吃了早饭来机房颓废. 10:00 似 ...

  3. SQLServer聚集索引导致的插入性能低

    1,新表默认会在主键上建立聚集索引.对于非专业DBA, 默认配置在大多数情况下够用. 2,当初为了优化查询速度. 把聚集索引建立在非自增主键的唯一索引列. 数据量上千万后,插入性能开始显现不足. 随着 ...

  4. linked-list-cycle-ii leetcode C++

    Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull. Follo ...

  5. hdu 1028 Ignatius and the Princess III(母函数)

    题意: N=a[1]+a[2]+a[3]+...+a[m];  a[i]>0,1<=m<=N; 例如: 4 = 4;  4 = 3 + 1;  4 = 2 + 2;  4 = 2 + ...

  6. .NET 开源工作流: Slickflow流程引擎高级开发(九) -- 条件事件模式解释及应用

    前言:在流程流转过程中,有时候需要条件模式的支持,这样可以使得流程流转更加灵活多变.比如在业务变量满足一定的条件时,可以启动特定配置的流程(或者位于主流程内部的子流程).本文主要描述条件启动和条件中间 ...

  7. Go语言并发模型 G源码分析

    Go 的线程实现模型,有三个核心的元素 M.P.G,它们共同支撑起了这个线程模型的框架.其中,G 是 goroutine 的缩写,通常称为 "协程".关于协程.线程和进程三者的异同 ...

  8. Java——去掉小数点后面多余的0

    当小数点后位数过多,多余的0没有实际意义,根据业务需求需要去掉多余的0.后端存储浮点型数据一般会用到Bigdecimal 类型,可以调用相关方法去掉小数后多余0,然后转为string. public ...

  9. IDEA中Update resources和Update classes and resources、Redeploy、Restart server的区别

    选项 描述 update resources 所有更改的资源都会更新(HTML,JSP,JavaScript,CSS和图像文件) update classes and resources 更改的资源将 ...

  10. css盒模型简介

    如何了解盒模型 盒模型简介:盒模型是css布局的基石,它规定了网页元素如何显示以及元素间相互关系.css定义所有的元素都可以拥有像盒子一样的外形和平面空间. 盒模型的组成:内容区.补白/填充.边框.边 ...