首页 > 其他分享 >适配器模式揭秘:让不兼容的组件完美协同

适配器模式揭秘:让不兼容的组件完美协同

时间:2023-12-15 14:08:12浏览次数:34  
标签:Target 适配器 模式 揭秘 public 接口 兼容 Adaptee


适配器模式揭秘:让不兼容的组件完美协同_java

前言

从这篇文章开始来盘一盘结构型设计模式,在开始之前先来简单回顾一下创建型的设计模式有哪些,如果有兴趣,就来一起学习吧:

设计模式之简单工厂模式

工厂方法模式:改变你对软件开发的认知_凡夫编程的技术博客_51CTO博客

抽象工厂模式:角色解析与应用探索_凡夫编程的技术博客_51CTO博客

设计模式之单例模式:不同实现方式的深度解析_凡夫编程的技术博客_51CTO博客

解密原型模式:工作原理与实际应用_凡夫编程的技术博客_51CTO博客

掌握建造者模式:构建复杂对象的灵活解决方案_凡夫编程的技术博客_51CTO博客

那么结构型的设计模式有哪些呢?结构型模式是用于处理类或对象的组合的设计模式,共七种,包括适配器模式、装饰者模式、代理模式、门面模式、桥梁模式、组合模式、享元模式。这篇文章的主角就是适配器模式。

什么是适配器模式

适配器模式(Adapter Pattern)允许将一个类的接口适配成用户所期待的接口,从而使原本因接口不兼容而不能在一起工作的类能够一起工作。

适配器模式分为两种类型:对象适配器模式和类适配器模式。

  1. 对象适配器模式:在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。
  2. 类适配器模式:这种适配器模式下,适配器继承自已实现的类。

适配器模式的核心原理

适配器模式的核心是将一个类的接口转换成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作。适配器模式是一种结构型设计模式,它通过引入一个适配器类来将不兼容的接口转换为兼容的接口。

适配器模式中有三个关键角色,分别是目标角色(Target)、源角色(Adaptee)和适配器角色(Adapter)。

  1. 目标(Target):目标接口,也就是我们期待的接口,客户端使用这个接口来调用适配器。
  2. 源(Adaptee):这是需要被适配的接口,通常也是需要被转换的接口。
  3. 适配器(Adapter):这是将源接口适配成目标接口的类。

适配器模式的核心是将两个没有关系的类组合在一起使用,只要传递了某个类的对象,就可以在适配器中调用这个类的方法。在实现适配器模式时,通常需要编写一个适配器类来实现目标接口,并将源接口转换为目标接口的实现方法。同时,还需要在客户端中使用目标接口来调用适配器的实例,从而间接地调用源接口的方法。

1、类的适配器模式:通过继承源接口类来实现适配,需要修改源接口类的继承结构。

适配器模式揭秘:让不兼容的组件完美协同_适配器模式_02

例如,将一个接口适配成另一个接口:

interface Target {    void request();}

class Adaptee {
    void specificRequest() {
        System.out.println("Adaptee's specific request.");
    }
}

class Adapter extends Adaptee implements Target {
    public void request() {
        specificRequest();
    }
}

在这个例子中,适配器Adapter继承了Adaptee类,实现了Target接口。适配器将Adaptee的特定请求(specificRequest)适配成Target接口的request方法。客户端通过Target接口来调用适配器,从而间接地调用Adaptee的特定请求。

2、对象适配器模式:通过将源对象封装在适配器对象中来实现适配,不需要修改源接口类的继承结构。

适配器模式揭秘:让不兼容的组件完美协同_适配器模式_03

例如,将一个类的对象适配成另一个类的对象:

interface Target {    void request();}class Adaptee {
    void specificRequest() {
        System.out.println("Adaptee's specific request.");
    }
}

class Adapter implements Target {
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    public void request() {
        adaptee.specificRequest();
    }
}

在这个例子中,适配器Adapter实现了Target接口。适配器将Adaptee的对象封装在适配器对象中,适配器的request方法通过调用Adaptee的特定请求(specificRequest)来实现适配。客户端通过Target接口来调用适配器,从而间接地调用Adaptee的特定请求。

适配器模式要解决什么问题

在计算机编程中,适配器模式可以用于解决接口不兼容的问题,它通过将一个类的接口包裹在一个已存在的类中,从而将该类的接口转换成客户所期待的接口。适配器的宗旨是保留现有类所提供的服务,向客户提供接口,以满足客户的期望。

在Java中,适配器模式如何实现

在生活当中,适配器的例子比比皆是,如在中国,生活用电的标准是220V的交流电,但是平常使用的手机的标准电压是5V的直流电,充电线末端的充电头实际上就是一个适配器,主要功能就是把220V的交流电转换成了手机需要的5V直流电。

/** * 5v直流电抽象接口类 */public interface DC5 {
    Integer outputDC5v();
}
/** * 220v交流电实体类 */public class AC220 {
    public Integer outputAc220v() {
        Integer output = 220;
        System.out.println("输出交流电:" + output + "V");
        return output;
    }
}

类适配器

适配器模式揭秘:让不兼容的组件完美协同_适配器模式_04

/** * 220v转5v适配器类 */public class PowerAdapter extends AC220 implements DC5{    @Override
    public Integer outputDC5v() {
        Integer outputAc220v = this.outputAc220v();
        System.out.println("适配器开始工作");
        int output5v = outputAc220v / 44;
        System.out.println("适配器输出电压:"+output5v+"5");
        return output5v;
    }
}

对象适配器

适配器模式揭秘:让不兼容的组件完美协同_适配器模式_05

/** * 220v转5v适配器类 */public class PowerAdapter2 implements DC5{    private AC220 ac220;    public PowerAdapter2(AC220 ac220) {
        this.ac220 = ac220;
    }

    @Override
    public Integer outputDC5v() {
        Integer outputAc220v = ac220.outputAc220v();
        System.out.println("适配器开始工作");
        int output5v = outputAc220v / 44;
        System.out.println("适配器输出电压:"+output5v+"5");
        return output5v;
    }
}
/** * 适配器模式 */public class Test {    public static void main(String[] args) {        //类适配器
        System.out.println("类适配器:--->");
        DC5 dc5=new PowerAdapter();
        dc5.outputDC5v();
        //对象适配器
        System.out.println("对象适配器:--->");
        AC220 ac220 = new AC220();
        DC5 dc52=new PowerAdapter2(ac220);
        dc52.outputDC5v();
    }
}

适配器模式揭秘:让不兼容的组件完美协同_设计模式_06

适配器模式有哪些应用场景

如果你在业务的开发过程中,遇到以下这些场景,就可以选择使用适配器模式,来使你的代码实现更优雅和高效:

  1. 系统需要使用现有的类,而此类的接口不符合需要。
  2. 需要一个统一的输出接口,而输入类型不可预知(如Android中的Adapter)。
  3. 创建一个可以复用的类(如Android中的Adapter),使得该类可以与其他不相关的类或不可预见的类协同工作。
  4. 你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。

适配器模式在Spring中有哪些应用

适配器模式在Spring框架中有多处应用:

  1. 在Spring的AOP模块中,适配器模式被用于增强被代理类的功能。例如,Spring的AOP模块提供了通知(Advice)来增强被代理类的功能,这些通知有BeforeAdvice、AfterReturningAdvice、ThrowsAdvice等类型。每种类型的Advice都有对应的拦截器,例如MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor。这些不同的拦截器通过适配器统一对外提供接口。
  2. 在Spring中,适配器模式也常被用于处理不同类型的“DisposableBean”。例如,当Spring容器启动时,会将所有“DisposableBean”添加到disposableBeans集合中。这些“DisposableBean”可能包括通过@Bean注入的实现了close方法的UserService、实现了DisposableBean接口的重写了destory()方法的类、实现了AutoCloseable接口的类等。在关闭容器销毁单例Bean时,Spring会找出实现了“DisposableBean”并执行对应的方法进行Bean的销毁。这就需要一个适配器,比如DisposableBeanAdapter,将这些判断封装起来,外部使用者直接调用DisposableBeanAdapter的destory()方法即可。

总结

优点:

  1. 提高类的透明性和复用,现有的类复用但不需要改变。
  2. 目标类和适配器类解耦,提高程序的扩展性。
  3. 在很多业务场景中符合开闭原则。

缺点:

  1. 适配器编写过程需要全面考虑,可能会增加系统的复杂性。
  2. 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。

标签:Target,适配器,模式,揭秘,public,接口,兼容,Adaptee
From: https://blog.51cto.com/fanfu1024/8840035

相关文章

  • 模拟适配器设计方案:360-基于10G以太网的模拟适配器
    基于10G以太网的模拟适配器一、产品概述   基于10G以太网的模拟适配器是一款分布式高速数据采集系统,实现多路AD的数据采集,并通过10G以太网光纤远距离传输到存储计算服务器,计算控制指令能通过光纤返回给数据卡进行IO信号控制。产品基于10G太网络,可迅速构建起......
  • 适配器模式
    适配器模式分为类适配器和对象适配器。适配器有三个角色,一个是目标(Target),一个是被适配者,一个是适配者。类适配器和对象适配器的区别是,类适配器是适配者继承目标(Targer)的同时也实现被适配者的抽象接口,对象适配器是适配者只继承目标(Targer),适配者内会有一个被适配者对象。示例代......
  • 揭秘IT行业市场现状,2024年成为程序员还有发展前景吗?
    前言IT行业的发展前景仍然非常广阔,尽管有一些声音认为该行业已经饱和,但实际上程序员仍然有大量的需求,并且薪资水平也在持续增长。首先,IT行业的发展速度非常快,新技术不断涌现,比如人工智能、大数据、云计算等等。这些新技术的应用范围越来越广泛,对程序员的需求也越来越大。因此,程序员......
  • 社会不教,精英不讲,坎儿还得自己过(揭秘人才成长规律)
    推荐大家去看看天涯社区的精华帖子:《社会不教,精英不讲,坎儿还得自己过(揭秘人才成长规律)》原出处天涯精华帖:《社会不教,精英不讲,坎儿还得自己过(揭秘人才成长规律)》原作者:e路狂飙原文完整PDF(估计很快就会被和谐,建议先保存):https://pan.quark.cn/s/7f8fe6532e85——愤青们的惨痛......
  • python 的 多个异步库如何兼容
    概述异步编程的重要性和不同的异步库介绍异步编程是现代软件开发中的重要概念,特别是在处理IO密集型任务时,它的作用尤为明显。不同的异步库为Python提供了多种不同的方式来实现异步编程。这些异步库包括但不限于asyncio、tornado、gevent等等。在本文中,我们将介绍这些不同的异步库及......
  • 兼容性复制功能/自定义mock数据/通用hook
    *****自定义mockconstresourceList=computed(()=>Array.from({length:20},(_,index)=>index).map((v,i)=>{return{id:i,joinList:Array.from({length:i},(_,index1)=>index1).map((v,......
  • Python办公自动化在Mac和Linux平台上的兼容性限制
    Python是一种强大的编程语言,被广泛应用于办公自动化领域。然而,有关Python办公自动化在Mac和Linux平台上的兼容性问题需要进行一定的探讨。本文将对Python办公自动化在Mac和Linux平台上的兼容性限制进行分析,并提供一些解决方案。Python是一种流行的编程语言,在办公自动化领域有着广泛......
  • 世微 AP5101C 兼容vas1086 高压线性降压恒流车灯驱动IC 宽压5-100V LED电源
      产品描述    AP5101C是一款高压线性LED恒流芯片,外围简单、内置功率管,适用于6-100V输入的高精度降压LED恒流驱动芯片。最大电流2.0A。AP5101C可实现内置MOS做2.0A,外置MOS可做3.0A的。AP5101C内置温度保护功能,温度保护点为130度......
  • 小心你的大模型被基准评估坑了,模型直接傻掉!人大高瓴揭秘大模型作弊
    作者|谢年年、Python从ChatGPT横空出世到国内外「百模大战」打响以来,我们隔三差五就会看到某某大模型又超越多个模型,刷新SOTA,成功屠榜的消息。这些榜单都是基于一系列高质量的评估基准创立的,从不同的方面比较LLMs的性能。典型的评估基准包括MMLU(用于衡量多任务语言理解能力)、Bi......
  • 面试题大揭秘:怎么使用自定义端口运行Spring应用?
    大家好,我是小米!今天我们要聊的话题是一道常见的面试题:怎么使用自定义端口运行Spring应用?这可是每个Java后端开发者都可能会遇到的问题哦!废话不多说,咱们直接进入主题。Spring应用的默认端口首先,让我们回顾一下Spring应用的默认端口。大多数情况下,当你启动SpringBoot应用时,它会在默......