Java结构型设计模式之适配器模式详解

 更新时间:2022年09月22日 10:33:38   作者:丨Jack_Chen丨  
适配器模式,即将某个类的接口转换成客户端期望的另一个接口的表示,主要目的是实现兼容性,让原本因为接口不匹配,没办法一起工作的两个类,可以协同工作。本文将通过示例详细介绍适配器模式,需要的可以参考一下

适配器模式

适配器模式(Adapter Pattern)又叫做变压器模式,属于结构型设计模式。

它的功能是将一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作。

适配器就像一个中间层,起着转化委托的作用,将一种接口转化为另一种符合需求的接口。

分类

适配器模式有3种形式:类适配器、对象适配器、接口适配器

类适配器:

类适配器的原理就是通过继承来实现适配器功能。

对象适配器:

对象适配器的原理就是通过组合来实现适配器功能。

接口适配器:

接口适配器的主要原理就是原理利用抽象类实现接口,并且空实现接口众多方法。

应用场景

1.已经存在的类,它的方法和需求不匹配(方法结果相同或相以)的情况。

2.适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不同厂家造成功能类似以而接口不相同情况下的解决方案。

说明:

当系统存在两种接口A和B,客户端只支持访问A接口,但是当前系统没有A接口对象,但是有B接口对象,但客户无法识别B接口,因此需要通过一个适配器C,将B接口内容转换成A接口,从而使得客户能够从A接口获取得到B接口内容。

举例:在不同的国家电源电压不一致,但是笔记本充电器通常有一个电压范围,其相当于使用了适配器,让其适应了不通过国家的电压。

优缺点

优点:

1.能提高类的透明性和复用,现有的类复用但不需要改变。

2.目标类和适配器类解耦,提高程序的扩展性。

3.在很多业务场景中符合开闭原则。

缺点:

1.适配器编写过程需要全面考虑,可能会增加系统的复杂性。

2.增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱。

主要角色

1.目标角色(Target)

目标角色也就是期望的接口

2.源角色(Adaptee)

存在于系统中,内容满足客户需求(需转换),但接口不匹配的接口实例

3.适配器(Adapter)

将源角色(Adaptee)转化为目标角色(Target)的类实例

适配器模式各角色之间的关系

需要的是Target接口,但Target接口设有一个实例符合需求,而Adaptee实例符合需求;但是无法直接使用Adaptee(接口不兼容);因此需要一个适配器(Adapter)来进行中转,让Adaptee能转化为Target接口形式;

类适配器

类适配器的原理就是通过继承来实现适配器功能。

让Adapter实现Target接口,并且继承Adaptee,这样Adapter就具备Target和Adaptee的特性,就可以将两者进行转化。

举例:以不同设备使用不同交流电为例,通过电源适配器进行转换说明。

创建目标角色(Target)

public interface Target {
    int out();
}

创建源角色(Adaptee)

public class Adaptee{
    public int input() {
        System.out.println("输入交流电: 220V");
        return 220;
    }
}

创建适配器(Adapter)

public class Adapter extends Adaptee implements Target {
    @Override
    public int out() {
        int input220V = super.input();
        int output = input220V / 2;
        System.out.println("输出交流电: " + output + "V");
        return output;
    }
}

客户端调用

    public static void main(String[] args) {
        Target adapter = new Adapter();
        int result = adapter.out();
        System.out.println(result);
    }

输入交流电: 220V
输出交流电: 110V
110

对象适配器

对象适配器的原理就是通过组合来实现适配器功能。

让Adapter实现Target接口,然后内部持有Adaptee实例,然后再Target接口规定的方法内转换Adaptee。

创建目标角色(Target)

public interface Target {
    int out();
}

创建源角色(Adaptee)

public class Adaptee{
    public int input() {
        System.out.println("输入交流电: 220V");
        return 220;
    }
}

创建适配器(Adapter)

public class Adapter implements Target {
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    @Override
    public int out() {
        int output = adaptee.input() / 2;
        System.out.println("输出交流电: " + output + "V");
        return output;
    }
}

客户端调用

    public static void main(String[] args) {
        Target adapter = new Adapter(new Adaptee());
        int result = adapter.out();
        System.out.println(result);
    }

输入交流电: 220V
输出交流电: 110V
110

接口适配器

接口适配器的关注点与类适配器和对象适配器的关注点不太一样,类适配器和对象适配器着重于将系统存在的一个角色(Adaptee)转化成目标接口(Target)所需内容,而接口适配器的使用场景是解决接口方法过多,如果直接实现接口,那么类会多出许多空实现的方法,类显得很臃肿。此时,使用接口适配器就能让我们只实现我们需要的接口方法,目标更清晰。

接口适配器的主要原理就是原理利用抽象类实现接口,并且空实现接口众多方法。

创建目标角色(Target)

public interface Target {
    int out1();
    int out2();
    int out3();
    int out4();
}

创建源角色(Adaptee)

public class Adaptee{
    public int input() {
        System.out.println("输入交流电: 220V");
        return 220;
    }
}

创建适配器(Adapter)

public class Adapter implements Target {
    protected Adaptee adaptee;
    public Adapter(Adaptee adaptee){
        this.adaptee = adaptee;
    }
    @Override
    public int out1() {
        int input220V = adaptee.input();
        int output = input220V / 1;
        System.out.println("输出交流电: " + output + "V");
        return output;
    }
    @Override
    public int out2() {
        int input220V = adaptee.input();
        int output = input220V / 2;
        System.out.println("输出交流电: " + output + "V");
        return output;
    }
    @Override
    public int out3() {
        return 0;
    }
    @Override
    public int out4() {
        return 0;
    }
}

客户端调用

    public static void main(String[] args) {
        Target adapter = new Adapter(new Adaptee());
        adapter.out1();
        System.out.println("---------------------");
        adapter.out2();
        System.out.println("---------------------");
        Target adapter2 = new Adapter(new Adaptee()) {
            @Override
            public int out3() {
                int input220V = adaptee.input();
                int output = input220V / 3;
                System.out.println("输出交流电: " + output + "V");
                return output;
            }
        };
        adapter2.out3();
        System.out.println("---------------------");
        Target adapter3 = new Adapter(new Adaptee()) {
            @Override
            public int out4() {
                int input220V = adaptee.input();
                int output = input220V / 4;
                System.out.println("输出交流电: " + output + "V");
                return output;
            }
        };
        adapter3.out4();
    }

输入交流电: 220V
输出交流电: 220V
---------------------
输入交流电: 220V
输出交流电: 110V
---------------------
输入交流电: 220V
输出交流电: 73V
---------------------
输入交流电: 220V
输出交流电: 55V

到此这篇关于Java结构型设计模式之适配器模式详解的文章就介绍到这了,更多相关Java适配器模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot启动时如何指定spring.profiles.active

    springboot启动时如何指定spring.profiles.active

    这篇文章主要介绍了springboot启动时如何指定spring.profiles.active问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • EL表达式简介_动力节点Java学院整理

    EL表达式简介_动力节点Java学院整理

    EL全名为Expression Language,这篇文章主要给大家介绍EL表达式的主要作用及内容简介,感兴趣的朋友一起看看
    2017-07-07
  • JAVA过滤器和拦截器有什么区别详细讲解

    JAVA过滤器和拦截器有什么区别详细讲解

    在JavaWeb开发中,过滤器(Filter)和拦截器(Interceptor)是两种重要的组件,主要用于拦截和处理请求,过滤器属于JavaServlet规范,用于请求到达目标资源之前或响应返回客户端之前的处理,需要的朋友可以参考下
    2024-10-10
  • IDEA新建bootstrap.yml文件不显示叶子图标的问题

    IDEA新建bootstrap.yml文件不显示叶子图标的问题

    这篇文章主要介绍了IDEA新建bootstrap.yml文件不显示叶子图标的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Mybatis源码分析之插件模块

    Mybatis源码分析之插件模块

    今天给大家带来的是关于Mybatis的相关知识,文章围绕着Mybatis插件模块展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下
    2021-06-06
  • 简单通用JDBC辅助类封装(实例)

    简单通用JDBC辅助类封装(实例)

    下面小编就为大家带来一篇简单通用JDBC辅助类封装(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • java中-jar 与nohup的对比

    java中-jar 与nohup的对比

    这篇文章主要介绍了java中 -jar 与nohup的对比的相关资料,需要的朋友可以参考下
    2017-05-05
  • 解决Maven的pom.xml中设置repository不起作用问题

    解决Maven的pom.xml中设置repository不起作用问题

    这篇文章主要介绍了解决Maven的pom.xml中设置repository不起作用问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • AsyncHttpClient IOExceptionFilter异常过滤器

    AsyncHttpClient IOExceptionFilter异常过滤器

    这篇文章主要为大家介绍了AsyncHttpClient IOExceptionFilter异常过滤器代码流程解读,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Java多线程 原子操作类详细

    Java多线程 原子操作类详细

    这篇文章主要介绍了Java多线程中的原子操作类,原子的本意是不能被分割的粒子,而对于一个操作来说,如果它是不可被中断的一个或者一组操作,那么他就是原子操作。显然,原子操作是安全的,因为它不会被打断,需要的朋友可以参考下
    2021-10-10

最新评论