23种设计模式(9)——适配器模式

news2024/12/26 9:21:28

目录

一、基本介绍

二、demo

2.1、类适配器模式

类适配器模式注意事项和细节

2.2、对象适配器模式

对象适配器模式注意事项和细节

2.3、接口适配器模式

 接口适配器模式介绍

三、适配器模式在框架中的应用

3.1在 SpringMVC 框架应用

3.2、spring AOP中的适配器模式


一、基本介绍

1) 适配器模式(Adapter Pattern)将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)

2) 适配器模式属于结构型模式

3) 主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

二、demo

2.1、类适配器模式

以生活中充电器的例子来讲解适配器,充电器本身相当于 Adapter,220V 交流电相当于 src (即被适配者),我们的目 dst(即 目标)是 5V 直流电。

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:45
 * @Des: 被适配者
 */
public class Voltage220V {

    public int output220V() {
        int src = 220;
        System.out.println("电压:" + src);
        return src;
    }
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des: 目标
 */
public interface IVoltage5V {
    int output5V();
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des: 适配器
 */
public class VoltageAdapter extends Voltage220V implements IVoltage5V{
    @Override
    public int output5V() {
        int srcV = output220V();
        int dstV = srcV / 44;
        return dstV;
    }
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:47
 * @Des: 使用者
 */
public class Phone {
    public void charging(IVoltage5V iVoltage5V) {
        if (iVoltage5V.output5V() == 5) {
            System.out.println("电压为5伏可以充电!");
        } else if (iVoltage5V.output5V() > 5) {
            System.out.println("电压不符!无法充电!");
        }
    }
}

测试:

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des:
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("适配器模式");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter());
    }
}

类适配器模式注意事项和细节

1) Java 是单继承机制,所以类适配器需要继承 src 类这一点算是一个缺点, 因为这要求 dst 必须是接口,有一定局限性;

2) src 类的方法在 Adapter 中都会暴露出来,也增加了使用的成本。

由于其继承了 src 类,所以它可以根据需求重写 src 类的方法,使得 Adapter 的灵活性增强了。

2.2、对象适配器模式

继续以生活中充电器的例子来讲解,充电器本身相当于 Adapter,220V 交流电相当于 src (即被适配者),我们的目 dst(即目标)是 5V 直流电,使用对象适配器模式完成。

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:57
 * @Des:
 */
public class VoltageAdapter2Object implements IVoltage5V {
    private Voltage220V voltage220V;

    public VoltageAdapter2Object(Voltage220V voltage220V) {
        this.voltage220V = voltage220V;
    }

    @Override
    public int output5V() {
        int dstV = 0;
        if (voltage220V != null) {
            int srcV = voltage220V.output220V();
            dstV = srcV / 44;
        }
        return dstV;
    }
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 14:46
 * @Des:
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("适配器模式");
        Phone phone = new Phone();
        //phone.charging(new VoltageAdapter());

        phone.charging(new VoltageAdapter2Object(new Voltage220V()));
    }
}

对象适配器模式注意事项和细节

1) 对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。

根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst必须是接口。

2) 使用成本更低,更灵活。

2.3、接口适配器模式

 接口适配器模式介绍

核心思路:当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求, 适用于一个接口不想使用其所有的方法的情况。

package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 15:03
 * @Des:
 */
public interface InterfaceTest {
    void method1();
    void method2();
    void method3();
    void method4();
    void method5();
}
package com.cjian.gof;

/**
 * @Author: cjian
 * @Date: 2023/4/20 15:04
 * @Des:
 */
public class AbstractAdapter implements InterfaceTest {
    @Override
    public void method1() {
    }

    @Override
    public void method2() {
    }

    @Override
    public void method3() {
    }

    @Override
    public void method4() {
    }

    @Override
    public void method5() {
    }

    public static void main(String[] args) {
        new AbstractAdapter() {
            @Override
            public void method1() {
                // TODO Auto-generated method stub
                super.method1();
            }
        };
    }
}

三、适配器模式在框架中的应用

3.1在 SpringMVC 框架应用

1) SpringMvc 中的 HandlerAdapter就使用了适配器模式

2) SpringMVC 处理请求的流程回顾:

DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由HandlerAdapter 适配器处理。HandlerAdapter 作为期望接口,具体的适配器实现类用于对目标类进行适配,Controller 作为需要适配的类。

为什么要在 Spring MVC 中使用适配器模式? Spring MVC 中的 Controller 种类众多,不同类型的 Controller 通过不同的方法来对请求进行处理。如果不利用适配器模式的话,DispatcherServlet 直接获取对应类型的 Controller,需要 if else 来进行判断是哪一种子类然后执行。

3.2、spring AOP中的适配器模式

我们知道 Spring AOP 的实现是基于代理模式,但是 Spring AOP 的增强或通知(Advice)使用到了适配器模式,与之相关的接口是AdvisorAdapter 。Advice 常用的类型有:BeforeAdvice(目标方法调用前,前置通知)、AfterAdvice(目标方法调用后,后置通知)、AfterReturningAdvice(目标方法执行结束后,return之前)等等。每个类型Advice(通知)都有对应的拦截器:MethodBeforeAdviceInterceptor、AfterReturningAdviceAdapter、AfterReturningAdviceInterceptor。Spring预定义的通知要通过对应的适配器,适配成 MethodInterceptor接口(方法拦截器)类型的对象(如:MethodBeforeAdviceInterceptor 负责适配 MethodBeforeAdvice)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/439255.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何制作实时库存报表

草料二维码暂不支持自动计算功能,无法看到实时的库存数量。但可以使用外部数据分析工具,如百度Sugar,连接草料二维码官方数据库,即可自由实现各类计算,包括实时库存。 一、案例效果 输入物料名称,即可快速…

oracle学习之rownum和rowid

rownum先百度一波https://www.cnblogs.com/xfeiyun/p/16355165.html rownum是oracle特有的一个关键字。 对于基表,在insert记录时,oracle就按照insert的顺序,将rownum分配给每一行记录,因此在select一个基表的时候,r…

Java基础(八)异常处理

1. 异常概述 1.1 什么是生活的异常 男主角小明每天开车上班,正常车程1小时。但是,不出意外的话,可能会出现意外。 出现意外,即为异常情况。我们会做相应的处理。如果不处理,到不了公司。处理完了,就可以…

Ubuntu下打开QtCreator,环境变量(PATH、LD_LIBRARY_PATH等)与预期不一致的问题

现象展示 在Ubuntu中,安装好Qt之后,可以在系统桌面的左下角找到启动图标 但是,这种方式启动的QtCreator所读取到的环境变量和我们从命令行读取到的不一致: 可以看到,明显少了这个:/opt/ros/humble/bin 因…

Docker实战笔记3-仓库

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/130260521 本文出自【赵彦军的博客】 文章目录 官方仓库 Docker Hub注册登录查看镜像搜索镜像推送镜像自动构建 网易镜像 官方仓库 Docker Hub https://hub.docker.com/ 目前 Docker 官方维护了…

C++入门之auto关键字内联函数

文章目录 前言一、auto关键字1.auto简介2.auto的使用细则(1)auto与指针和引用结合起来使用(2)在同一行定义多个变量(3)auto不能推导的场景 3.基于范围的for循环(C11)(1)遍历&#xf…

聚观早报|五一首日高铁跨省游热度暴涨;大语言模型规模接近极限

今日要闻:马斯克已创立新人工智能公司X.AI;五一假期首日高铁跨省游热度暴涨;大语言模型规模已接近极限;贾跃亭发文谈FF首台量产车下线;斑马智行与智己汽车进一步合作 马斯克已创立新人工智能公司X.AI 据外媒报道&…

Node 07-nvm

nvm 介绍 nvm 全称 Node Version Manager 顾名思义它是用来管理 node 版本的工具,方便切换不同版本的Node.js 使用 nvm 的使用非常的简单,跟 npm 的使用方法类似 下载安装 首先先下载 nvm,下载地址 https://github.com/coreybutler/nvm-…

【Python中线程和进程详解】

一.区别 几乎所有的操作系统都支持同时运行多个任务,每个任务通常是一个程序,每一个运行中的程序就是一个进程,即进程是应用程序的执行实例。现代的操作系统几乎都支持多进程并发执行。 注意,并发和并行是两个概念,并…

好家伙,9:00面试,9:06就出来了,问的实在是太...

从外包出来,没想到死在另一家厂子 自从加入这家公司,每天都在加班,钱倒是给的不少,所以也就忍了。没想到2月一纸通知,所有人不许加班,薪资直降30%,顿时有吃不起饭的赶脚。 好在有个兄弟内推我去…

会声会影老牌视频剪辑软件2023新版本升级

会声会影2023(VideoStudio)是一款功能强大的专业视频制作软件的视频编辑软件及视频剪辑软件,可以剪辑&合并视频、制作视频、屏幕录制、光盘制作、视频后期编辑、添加特效、字幕和配音等操作,任何人都能快速上手,以它的界面美观&#xff0…

#关于webpack版本号的问题#

场景:在使用npm install 安装package.json里面的依赖的,打包,运行的使用,有时候会失败。 原因 :由于webpack webpack-cli版本不同导致的 这个时候需要解决webpack webpack-cli的安装,切换等操作 例如使用…

python+vue 智慧校园校医室问诊系统

本网站所实现的是一个智慧校园校医室问诊系统,该系统严格按照需求分析制作相关模块,并利用所学知识尽力完成,但是本人由于学识浅薄,无法真正做到让该程序可以投入市场使用,仅仅简单实现部分功能,希望日后还…

CentOS8使用cephadm部署和配置Ceph Octopus

部署工具:cephadm操作系统:CentOS 8Ceph版本:Octopus操作用户:root 部署前,请注意:根据目前(2020年8月)Ceph官方文档的介绍,cephadm的对各服务的支持情况如下&#xff1a…

3D WEB端渲染引擎如何使用服务器端的转换程序?1个案例教会你

前言 HOOPS SDK是用于3D工业软件开发的工具包,其中包括4款工具,分别是用于读取和写入30多种CAD文件格式的HOOPS Exchange、专注于Web端工程图形渲染的HOOPS Communicator、用于移动端和PC端工程图形渲染的HOOPS Visualize、支持将3D数据以原生3D PDF、H…

html+css+js本地音乐播放器,实现可视化音频频谱

效果 htmlcssjs本地音乐播放器,实现可视化音频频谱 前言 之前用swing写了个本地音乐播放器(如下图),但是效果一言难尽,界面丑,功能bug也多,唉 所以后面又重新用html写了个,界面样式…

港联证券:为什么会出现股票跌停?股票跌停应该怎么卖出?

股票跌停的意思是股票跌落到交易规则设定的涨跌幅限制范围外,致使股票无法正常卖出的现象。那么为什么会呈现股票跌停?股票跌停应该怎样卖出?下面就由港联证券为大家分析: 为什么会呈现股票跌停? 1、主力出货 当某只…

【竞赛知识ONE】取余问题

前言: 在一些竞赛题中,往往要求对最终的数据结果进行取余或者求模运算。但是如果仅仅只是在输出最终结果的时候对某个数取模,那么可能会导致数据溢出等问题,所以在计算过程中也需要对中间数据进行取模操作。 定理: 举例: 1. 案例一 解题分析:思路并不难理解计算…

TryHackMe-Fusion Corp(ez Windows域渗透)

Fusion Corp 你不久前与Fusion Corp联系。他们联系了你,说他们已经修补了所有报告的内容,你可以开始重新测试了。 端口扫描 循例nmap 将fusion.corp域名加入hosts Web枚举 gobuster扫 访问backup 下载该文件,打开发现是一些用户名 保存下来…

大模型的三大法宝:Finetune, Prompt Engineering, Reward

编者按:基于基础通用模型构建领域或企业特有模型是目前趋势。本文简明介绍了最大化挖掘语言模型潜力的三大法宝——Finetune, Prompt Engineering和RLHF——的基本概念,并指出了大模型微调面临的工具层面的挑战。 以下是译文,Enjoy! 作者 | B…