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,方便在应用程序中进行调用。

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

相关推荐
小码的头发丝、17 分钟前
Django中ListView 和 DetailView类的区别
数据库·python·django
Chef_Chen1 小时前
从0开始机器学习--Day17--神经网络反向传播作业
python·神经网络·机器学习
千澜空1 小时前
celery在django项目中实现并发任务和定时任务
python·django·celery·定时任务·异步任务
斯凯利.瑞恩2 小时前
Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户附数据代码
python·决策树·随机森林
yannan201903132 小时前
【算法】(Python)动态规划
python·算法·动态规划
蒙娜丽宁2 小时前
《Python OpenCV从菜鸟到高手》——零基础进阶,开启图像处理与计算机视觉的大门!
python·opencv·计算机视觉
光芒再现dev2 小时前
已解决,部署GPTSoVITS报错‘AsyncRequest‘ object has no attribute ‘_json_response_data‘
运维·python·gpt·语言模型·自然语言处理
好喜欢吃红柚子2 小时前
万字长文解读空间、通道注意力机制机制和超详细代码逐行分析(SE,CBAM,SGE,CA,ECA,TA)
人工智能·pytorch·python·计算机视觉·cnn
小馒头学python2 小时前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习
神奇夜光杯3 小时前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长