6、设计模式之适配器模式(Adapter)

一、什么是适配器模式

适配器模式是一种结构型设计模式,它允许将不兼容的对象转换成可兼容的接口主要目的是解决在不改变现有代码的情况下,使不兼容的接口之间能够正常工作,通过创建一个中间转换的适配器来将一个对象转换成我们所需要的接口。

二、角色组成

目标接口(target):需要适配的标准接口。

源对象(source):需要被适配的不兼容对象。

适配器对象(adapter):充当中间转换角色,该对象将源对象转换成目标接口。

三、优缺点

优点:

安全可靠:封装了旧接口,对客户端透明,客户端代码无需修改。 提高复用性:可以复用不兼容的类;可以对不同的类无需修改,就可以进行组合。

扩展性好:在应用程序开发过程中,可以增加新的适配器和被适配对象。

缺点:

过多的适配器会导致系统结构复杂。 如果适配器没有实现好,可能会拖慢整个系统的性能。 滥用适配器模式会导致系统设计紊乱。

四、应用场景

4.1 生活场景

电压转换器:不同国家的电压规格各异,同样功率的电器在不同的地方工作时需要不同的电压,电压转换器作为适配器,将不同电压转换成电器使用标准电压。

耳机转接头:有些手机没有耳机插口,需要使用转接头适配器,将耳机转换为手机支持的接口,实现对不同的耳机兼容。

4.2 java场景

JDBC驱动程序:不同的数据库提供商实现了不同的JDBC驱动接口,使用适配器模式可以将这些不同的接口适配为标准的JDBC接口,提高应用程序的可移植性。

日志框架:Java中有多个常用的日志框架,如Log4j、SLF4J等,不同的日志框架提供的API不同,使用适配器模式可以将这些不同的API适配为一个统一的接口,方便再程序中进行日志记录和管理。

第三方库或SDK:在使用第三方库或 SDK 时,可能由于它们实现的 API 不同而导致应用程序复杂,使用适配器模式可以将不同的 API

适配为统一的接口,简化应用程序的调用。

五、代码实现

当我们去国外旅游时,我们可能只会汉语,而当地人只会英语,那么这个时候就需要一个翻译员(翻译软件)来帮助我们。这就类似于适配器模式,通过一个适配器将一个不兼容的接口转成另外一个接口。下面以翻译为例,介绍一下类、接口、对象适配器。

5.0 代码结构

5.1 类适配器模式

使用继承的方式,将需要适配的类转换为目标接口的子类,实现目标接口的所有方法,同时继承适配类的实现,用以完成一些适配逻辑。

java 复制代码
/**
 * 
 * 目标接口(target)
 */
public interface Target {
 
    /**
     * 翻译
     * @param source 母语
     * @param target 要翻译成的语种
     * @param words 内容
     */
    void translate(String source,String target,String words);
}

翻译类'Translator' ,里面有'TranslateInZh'和'TranslateInEn'方法。(对象、接口适配器模式也要用)

java 复制代码
/**
 *
 * 源对象(source):充当翻译
 */
public class Translator {
 
    //英------》汉
    public void translateInZh(String words){
        if("hello world!".equals(words)){
            System.out.println("翻译成中文:"你好世界!"");
        }
    }
 
    //汉------》英
    public void translateInEn(String words){
        if("你好世界!".equals(words)){
            System.out.println("Translate in English:"hello world!"");
        }
    }
}

ClassAdapter

java 复制代码
/**
 * 
 * 类适配器:通过多重继承目标接口和被适配者类方式来实现适配
 */
public class ClassAdapter extends Translator implements Target {
 
    @Override
    public void translate(String source, String target, String words) {
        if("中文".equals(source) && "英文".equals(target)) {
            //汉--》英
            this.translateInEn(words);
        } else {
            //英--》汉
            this.translateInZh(words);
        }
    }
}

testClassAdapter

java 复制代码
/**
 * 
 */
@SpringBootTest
public class TestAdapter {
 
    //类适配器
    @Test
    void classAdapter(){
        //创建一个类适配器对象
        ClassAdapter adapter=new ClassAdapter();
        adapter.translate("中文", "英文", "你好世界!");
        adapter.translate("英语","中文","hello world!");
    }
}

5.2 对象适配器模式

通过组合的方式,将适配对象与目标接口组合,实现目标接口的所有方法,并在适配类中调用需要适配对象的方法。

ObjectAdapter

java 复制代码
/**
 * 
 * 对象适配器:使用组合的方式
 */
public class ObjectAdapter implements Target {
 
    private Translator translator=new Translator();
 
    @Override
    public void translate(String source, String target, String words) {
        if("中文".equals(source) && "英文".equals(target)) {
            //汉--》英
            translator.translateInEn(words);
        } else {
            //英--》汉
            translator.translateInZh(words);
        }
    }
}

testObjectAdapter

java 复制代码
/**
 * @author Created by njy on 2023/6/8
 */
@SpringBootTest
public class TestAdapter {
    //对象适配器
    @Test
    void ObjectAdapter(){
        ObjectAdapter adapter=new ObjectAdapter();
        adapter.translate("中文", "英文", "你好世界!");
        adapter.translate("英语","中文","hello world!");
    }
}

5.3 接口适配器模式

主要适用于需要被适配的接口中,只有用到个别接口,也就是说不需要实现它的全部接口。通过一个中间抽象类或接口实现。

target2:用于解释接口适配器

java 复制代码
/**
 * 
 * target2:用于解释接口适配器
 */
public interface target2 {
    /**
     * 翻译
     * @param source 母语
     * @param target 要翻译成的语种
     * @param words 内容
     */
    void translate(String source,String target,String words);
 
    //无用方法,仅仅用来说明接口适配器
    void a();
}

AbstractAdapter抽象类

java 复制代码
InterfaceAdapter:接口适配器

/**
 * 
 * 接口适配器:当不需要全部实现接口方法时。
 * 可以先设计一个抽象类实现接口AdapterTranslate
 * AdapterTranslate实现,不用去实现b()方法
 */
public class InterfaceAdapter extends AbstractAdapter {
 
 
    public void translate(String source, String target, String words) {
       super.translate(source,target,words);
    }
}

testInterfaceAdapter

java 复制代码
/**
 * @author Created by njy on 2023/6/8
 */
@SpringBootTest
public class TestAdapter {
 
    //接口适配器
    @Test
    void interfaceAdapter(){
        InterfaceAdapter adapter=new InterfaceAdapter();
        adapter.translate("中文", "英文", "你好世界!");
        adapter.translate("英语","中文","hello world!");
    }
 
}

六、总结

适配器模式的适用场景:

重用现有的代码:适配器模式可以允许我们重用已有的类或接口,而不需要修改其原有的代码。

集成老系统:当现有的系统不满足用户需求时,需要增加系统功能或接口。但是,老系统的接口可能与现有的技术、平台不兼容,此时可以采用适配器模式,将现有的接口适配为新的接口,从而实现新系统的集成。

集成第三方组件:在使用第三方组件时,可能由于它们实现的 API 不同而导致应用程序复杂,此时可以使用适配器模式,将第三方组件提供的 API 适配为自己需要的 API,方便在应用程序中进行调用。

实现跨平台兼容:在不同平台、不同技术栈之间进行开发时,常常需要适配不同的接口,以使得不同的平台或技术栈之间能够相互兼容,此时可以使用适配器模式来处理各种不兼容问题。

相关推荐
waterHBO1 小时前
python 爬虫 selenium 笔记
爬虫·python·selenium
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
AIAdvocate4 小时前
Pandas_数据结构详解
数据结构·python·pandas
小言从不摸鱼4 小时前
【AI大模型】ChatGPT模型原理介绍(下)
人工智能·python·深度学习·机器学习·自然语言处理·chatgpt
FreakStudio6 小时前
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
python·嵌入式·面向对象·电子diy
redcocal7 小时前
地平线秋招
python·嵌入式硬件·算法·fpga开发·求职招聘
artificiali8 小时前
Anaconda配置pytorch的基本操作
人工智能·pytorch·python
RaidenQ8 小时前
2024.9.13 Python与图像处理新国大EE5731课程大作业,索贝尔算子计算边缘,高斯核模糊边缘,Haar小波计算边缘
图像处理·python·算法·课程设计
花生了什么树~.8 小时前
python基础知识(六)--字典遍历、公共运算符、公共方法、函数、变量分类、参数分类、拆包、引用
开发语言·python
Trouvaille ~9 小时前
【Python篇】深度探索NumPy(下篇):从科学计算到机器学习的高效实战技巧
图像处理·python·机器学习·numpy·信号处理·时间序列分析·科学计算