资讯专栏INFORMATION COLUMN

Java设计模式之(八)——适配器模式

番茄西红柿 / 3043人阅读

摘要:适配器模式应用场景适配器模式应用场景修改已使用的接口某个已经投产中的接口需要修改,这时候使用适配器最好。适配器模式适配器模式是一种事后的补救策略。

1、什么是适配器模式?

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

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

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

2、适配器模式定义

image-20210910001149584

①、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();    }}

打印结果:

image-20210910084111245

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

①、如果 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、代理-桥接-装饰器-适配器区别

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

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

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

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

作者:IT可乐

资源:微信搜【IT可乐】关注我,回复 【电子书】有我特别筛选的免费电子书。
本文版权归作者所有,欢迎转载,但未经作者同意不能转载,否则保留追究法律责任的权利。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/125109.html

相关文章

  • Java学习路线总结,搬砖工逆袭Java架构师(全网最强)

    摘要:哪吒社区技能树打卡打卡贴函数式接口简介领域优质创作者哪吒公众号作者架构师奋斗者扫描主页左侧二维码,加入群聊,一起学习一起进步欢迎点赞收藏留言前情提要无意间听到领导们的谈话,现在公司的现状是码农太多,但能独立带队的人太少,简而言之,不缺干 ? 哪吒社区Java技能树打卡 【打卡贴 day2...

    Scorpion 评论0 收藏0
  • JavaScript设计模式系列:外观模式

    摘要:外观模式外观模式是指提供一个统一的接口去访问多个子系统的多个不同的接口,为子系统中的一组接口提供统一的高层接口。外观模式在我们的日常工作中十分常见。 外观模式 外观模式是指提供一个统一的接口去访问多个子系统的多个不同的接口,为子系统中的一组接口提供统一的高层接口。使得子系统更容易使用,不仅简化类中的接口,而且实现调用者和接口的解耦。外观模式在我们的日常工作中十分常见。 我们来看一个例子...

    tianren124 评论0 收藏0
  • 开发路(设计模式:外观模式

    摘要:改变接口的新模式,为了简化接口这次带来的模式为外观模式,之所以这么称呼,因为它将一个或多个类复杂的一切都隐藏起来。 改变接口的新模式,为了简化接口 这次带来的模式为外观模式,之所以这么称呼,因为它将一个或多个类复杂的一切都隐藏起来。 我依旧举生活中例子,现在有些朋友家的液晶电视可能是大尺寸的,或者有用投影仪来看电视,打游戏的。有一天我想用家庭影院系统在家里看一次大片。 ...

    hosition 评论0 收藏0
  • 你和阿里资深架构师间,差的不仅仅是年龄(进阶必看)

    摘要:导读阅读本文需要有足够的时间,笔者会由浅到深带你一步一步了解一个资深架构师所要掌握的各类知识点,你也可以按照文章中所列的知识体系对比自身,对自己进行查漏补缺,觉得本文对你有帮助的话,可以点赞关注一下。目录一基础篇二进阶篇三高级篇四架构篇五扩 导读:阅读本文需要有足够的时间,笔者会由浅到深带你一步一步了解一个资深架构师所要掌握的各类知识点,你也可以按照文章中所列的知识体系对比自身,对自己...

    huaixiaoz 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<