适配器模式

适配器模式(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适配器模式内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Java结构型设计模式之适配器模式详解的更多相关文章

  1. 如何从 Parse 手中拯救你的应用

    Parse即将关闭...你打算怎么办呢?今年1月28号,Parse宣布它将会关闭自己的服务。Parse在2013年被Facebook以八千五百万美元收购,但现在“五巨头”之首冷血地切断了对开发者们应用的支撑服务。对开发者来说,Parse的关闭是一个机会在我做应用之前,我一直在开发网站。我常常将Parse解释为“应用的电子表格”。即使你想从Parse转到Firebase,因为你的代码和后端紧密耦合,你不得不在迁移之前重写整个应用。

  2. Swift设计模式之适配器模式

    转自Swift设计模式原文Design-Patterns-In-Swift

  3. MVVM 不是那么好

    我觉得MVVM是一种反人类的设计模式,它使架构更加混乱而非清晰。MVVM命名很糟糕名称是很重要的。ViewModel这一名称则没有发挥任何作用。ViewModel的第一种含义是modelfortheview。MVVM引进太多职责命名不够具体,导致这个类的任务无休止地增长。MVVM不改变你的架构viewmodel并不能从根本上改变你的应用程序的架构。我能想到的MVVM模式最大的好处就是它把“下水道”从苹果自带的viewcontrooller类转移到了viewmodel这一自定义的对象。

  4. 开发Swift iOS应用程序“正确的方式”

    最近,我学习了Swift和开发iOS应用程序的基础知识。现在,我想自己开发一个真正的应用程序,但我非常关心编写好的代码,所以我已经寻找“最佳实践”,“设计模式”和“正确的方式”来实现它。在我的搜索中,我发现这个greattutorial关于SwiftiOS应用程序中通常使用的所有设计模式,以及他们使用的示例。不应该将httpClient和persistencyManager声明为协议,然后HttpClient和PersistencyManager类实现该协议?我应该在哪里告诉应用程序?最后但并非最不重要的

  5. android – 数组适配器notifyDataSetChanged()将无法正常工作

    .有任何想法吗?

  6. Android刷新适配器工作后再次旋转设备

    当我将一些数据添加到“列表模型”中并且在旋转设备上恢复保存的数据时,此代码工作正常,不幸的是,在恢复数据并将其设置为在OnRestoreInstanceState方法之后建模,在添加其他数据后,适配器无法使用新添加的数据刷新,适配器中的数据源可以更新,但适配器可以;不知道他们,我使用MVVM数据模型绑定和搜索更多的时间关于这个问题我无法解决.Rhat有一个简单的提示,再次旋转设备后,我的适配器可以

  7. android – 适配器在Mvp模式中的作用?

    你如何对待MVP模式中的适配器?具体来说,在这种情况下,您是否在适配器中有presenter对象,或者有视图对象来执行调用,通知和加载?

  8. Android粘贴标题RecyclerView / Section Header RecyclerView

    你好所有我刚刚创建了一个演示来使用新的AndroidL小部件RecyclerView.I也实现了拉动刷新使用SwipeRefreshLayout,但我现在的问题是如何在这里实现粘性标题,因为当我尝试设置我只得到这两个方法,所以没有任何想法如何处理这个…等等.背后的想法是避免从头开始创建每个项目的自定义适配器,并在一个库中具有更多功能,而不是依赖于仅支持其中1个或3个而不能合并的不同库.

  9. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. javascript的23种设计模式示例总结大全

    这篇文章主要为大家介绍了javascript的23种设计模式的总结大全,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部