「聊设计模式」之适配器模式(Adapter)

举报
bug菌 发表于 2023/09/25 16:34:19 2023/09/25
【摘要】 适配器模式是一种结构型设计模式,它可以将一个类的接口转换为客户希望的另一个接口。适配器模式将原来不兼容的类结合在一起工作,增加了系统的灵活性和可复用性。


🏆本文收录于《聊设计模式》专栏,专门攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎持续关注&&收藏&&订阅!


大家下午好,我是bug菌,今天我们继续聊设计模式。

前言

  在软件开发中,经常会涉及到现有系统的改造和升级。为了适应新的需求,我们需要对旧系统进行修改,但是,这些修改可能会破坏原有的架构,给系统带来风险。适配器模式(Adapter)可以在不改变原有系统的基础上,将新需求的接口转换为旧系统的接口,实现两者之间的兼容性。

摘要

  适配器模式是一种结构型设计模式,它可以将一个类的接口转换为客户希望的另一个接口。适配器模式将原来不兼容的类结合在一起工作,增加了系统的灵活性和可复用性。

适配器模式

概念

  适配器模式由三个角色组成:目标抽象类、适配器类和适配者类。

  • 目标抽象类:定义客户所需接口,可以是一个抽象类或接口。
  • 适配器类:实现目标接口,并持有适配者对象的引用。
  • 适配者类:旧的接口实现类,不符合客户需求。

  适配器模式的核心思想是通过适配器类在目标抽象类和适配者类之间建立一个桥梁,使得两者可以协同工作,实现客户所需要的功能。

模式结构

  适配器模式(Adapter Pattern)是一种结构型设计模式,它允许将不兼容的对象封装到一个适配器中,以使其与另一个对象相兼容。

适配器模式的结构包括以下几个角色:

  1. 目标抽象类(Target):定义客户端使用的业务接口,客户端通过该接口访问适配器中封装的对象。

  2. 适配器类(Adapter):将不兼容的对象适配成目标抽象类所定义的接口,适配器类通常包含一个或多个被适配的对象。

  3. 被适配者类(Adaptee):原本不兼容的对象,它需要被适配器适配成目标抽象类所定义的接口。

  4. 客户端(Client):通过目标抽象类定义的接口访问适配器中封装的对象。

适配器模式的结构可以用以下UML图表示:

image.png

  适配器模式的基本思想是将一个对象转换成另一个对象,以满足客户端的需求。适配器模式通常用于系统的升级和维护,它能够很好地解决系统中存在的兼容性问题。

优缺点

优点

适配器模式(Adapter)的优点:

  1. 可以让两个不兼容的接口协同工作;
  2. 可以让客户端使用已经存在的类而不需要修改其代码;
  3. 可以提高代码的复用性和灵活性。

缺点

适配器模式(Adapter)的缺点:

  1. 增加了代码的复杂度;
  2. 需要进行额外的编码工作;
  3. 如果适配器类过多,会导致系统难以维护。
  4. 在不适当的情况下使用适配器模式可能会导致代码难以理解和调试。

应用场景

适配器模式的应用场景如下:

  1. 系统需要使用现有的类,而这些类的接口不符合系统的需要,可以使用适配器模式将现有的接口转为系统需要的接口。

  2. 对于一些已经存在的类,他们的接口设计不符合需求,但是这些类又是不可修改的,可以通过适配器模式来重新封装这些类,使其满足需求。

  3. 在开发阶段,为了减少系统的耦合度,可以使用适配器模式将两个独立的系统集成在一起。

  4. 对于多个类似但是不同的类,可以使用适配器模式来统一它们的接口,从而使得这些类能够被同一种方式使用。

模式实现

  我们以Java语言为例,来演示适配器模式的实现。假设我们有一个旧的类OldServiceImpl,它提供了一个方法oldMethod,但是它的接口不符合我们的需求。我们需要将它的接口转换为我们需要的NewService接口。

public class OldServiceImpl {
    public void oldMethod() {
        // 旧的接口实现
        System.out.println("旧的接口实现");
    }
}

  首先,我们需要定义一个目标抽象类NewService,它定义了我们需要的接口。

public interface NewService {
    void newMethod();
}

  然后,我们需要创建一个适配器类Adapter,它实现了NewService接口,并持有OldServiceImpl对象的引用。在newMethod方法中,调用OldServiceImploldMethod方法。

public class Adapter implements NewService {
    private OldServiceImpl oldServiceImpl;

    public Adapter(OldServiceImpl oldServiceImpl) {
        this.oldServiceImpl = oldServiceImpl;
    }

    @Override
    public void newMethod() {
        oldServiceImpl.oldMethod();
    }
}

  最后,我们可以使用适配器模式将旧的接口转换为新的接口。

package com.example.javaDesignPattern.adapter;

/**
 * @author bug菌
 * @version 1.0
 * @date 2023/9/19 11:02
 */
public class Client {
    public static void main(String[] args) {
        OldServiceImpl oldServiceImpl = new OldServiceImpl();
        NewService newService = new Adapter(oldServiceImpl);
        newService.newMethod();
    }
}

执行结果如下:

image.png

代码解读

这段代码是一个简单的测试类,用于测试适配器模式。其中:

  • OldServiceImpl 是一个已经存在的、老的服务接口实现类。
  • NewService 是一个新的服务接口,它有 OldService 中没有的新方法。
  • Adapter 是适配器类,它实现了 NewService 接口,并将 NewService 的方法调用转化为 OldService 的方法调用。

  定义了一个名为 adapter 的类,并在其中创建了一个 main 方法作为程序的入口。在 main 方法中,首先实例化了一个 OldServiceImpl 对象,然后通过创建一个名为 Adapter 的适配器对象,将旧服务的实现对象 oldServiceImpl 适配成了新服务的实现对象,即将其转换为 NewService 接口能够调用的对象。最后,调用新服务的 newMethod 方法,测试转换是否成功。

小结

  适配器模式是一种常用的设计模式,它可以将旧的接口转换为新的接口。通过适配器模式,我们可以兼容现有系统和新需求之间的差异,同时提高系统的灵活性和可复用性。

附录源码

  如上涉及代码均已上传同步在 GitHub,提供给同学们参考性学习。

总结

  适配器模式是一种结构型设计模式,它允许我们将一个类的接口转换为客户所期望的另一个接口。通过适配器模式,我们可以在不改变原有系统的基础上,实现新需求和旧系统之间的兼容性。适配器模式的核心思想是通过适配器类在目标抽象类和适配者类之间建立一个桥梁,使得两者可以协同工作。

☀️建议/推荐你


  如果想系统性的全面学习设计模式,建议小伙伴们直接毫无顾忌的关注这个专栏《聊设计模式》,无论你是想提升自己的编程技术,还是渴望更好地理解代码背后的设计思想,本专栏都会为你提供实用的知识和启发,帮助你更好地解决日常开发中的挑战,将代码变得更加优雅、灵活和可维护!

  最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。

  同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。

📣关于我

  我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。