设计模式学习——适配器模式

血管分割中的直径平衡难题:从clDice到cbDice的演进与实践 本文探讨了血管分割中的直径平衡难题,详细分析了从clDice到cbDice的技术演进与实践。通过引入半径感知权重和边界对齐惩罚,cbDice在保持拓扑完整性的同时提升了几何敏感度,显著改善了细小血管的分割效果。文章还分享了在nnU-Net中实现cbDice的工程细节,包括GPU加速骨架提取和多任务损失组合策略,为医学影像分析提供了重要参考。 阅读详情


适配器模式

基本介绍

  1. 适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主要的目的是:让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)
  2. 适配器模式属于结构型模式
  3. 主要分为三类:类适配器模式、对象适配器模式、接口适配器模式

工作原理

  1. 适配器模式:将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容。
  2. 从用户的角度看不到被适配者,是解耦的。
  3. 用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法
  4. 用户收到反馈结果,感觉只是和目标接口交互。
    在这里插入图片描述

类适配器模式

类适配器模式介绍

Adapter类,
通过集成src类,实现dst接口,
完成src——>的适配

类适配器模式类图实例

在这里插入图片描述

类适配器模式代码实例

Voltage220V 类

public class Voltage220V {
    int src = 220;

    public int output220V() {
        System.out.println("电压=" + src + "伏");
        return src;
    }
}

Voltage5V 接口

public interface Voltage5V {
    public int output5V();
}

VoltageAdapter类作为适配器

public class VoltageAdapter extends Voltage220V implements Voltage5V {

    @Override
    public int output5V() {
        int src = output220V();
        int dstV = src / 44;
        return dstV;
    }
}

Phone 具体的实现

public class Phone {

    public void charging(Voltage5V voltage5V){
        if (voltage5V.output5V()==5){
            System.out.println("电压为5V,可以充电~~~");
        }else if (voltage5V.output5V()>5){
            System.out.println("电压大于5V,不能充电~~");
        }
    }
}

测试用例

public class Client {
    public static void main(String[] args) {
        System.out.println("=== 类适配器模式 ===");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter());
    }
}
类适配器模式注意事项和细节
  1. Java是单继承机制,所以类适配器需要继承src类这一点算是一个缺点,因为这要求dst必须是接口,有一定局限性;
  2. src类的方法在Adapter中都会暴露出来,也增加了使用的成本。
  3. 由于其继承了src类,所以它可以根据需求重写src类的方法,使得Adapter的灵活性增强了。

对象适配器模式

对象适配器模式介绍
  1. 基本思路和类的适配器模式相同,只是将Adapter类作修改,不是继承src类,而是持有src类的实例,以解决兼容性的问题。即:持有src类,实现dst类接口,完成src——>dst的适配
  2. 根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系。
  3. 对象适配器模式是适配器模式常用的一种。

对象适配器模式类图实例

在这里插入图片描述

对象适配器模式代码实例

Voltage220V类

public class Voltage220V {
    int src = 220;

    public int output220V() {
        System.out.println("电压=" + src + "伏");
        return src;
    }
}

Voltage5V 接口

public interface Voltage5V {
    public int output5V();
}

VoltageAdapter 发生了变化,不再继承Voltage220V类,而是采用聚合的方式,降低了两个类之间的耦合关系,减小了类之间的入侵,符合开闭原则和合成复用原则。

public class VoltageAdapter implements Voltage5V {

    private Voltage220V voltage220V = null;

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

    @Override
    public int output5V() {
        int dst = 0;
        if (null != voltage220V) {
            int src = voltage220V.output220V();
            System.out.println("使用对象适配器,进行适配~~");
            dst = src/44;
            System.out.println("适配完成,输出的电压为="+dst);
        }
        return dst;
    }
}

Phone 类

public class Phone {

    public void charging(Voltage5V voltage5V){
        if (voltage5V.output5V()==5){
            System.out.println("电压为5V,可以充电~~~");
        }else if (voltage5V.output5V()>5){
            System.out.println("电压大于5V,不能充电~~");
        }
    }
}

Client测试用例中新增了一个new Voltage220V(),是因为在初始化VoltageAdapter类时,其触发了含参构造器。

public class Client {
    public static void main(String[] args) {
        System.out.println("=== 类适配器模式 ===");
        Phone phone = new Phone();
        phone.charging(new VoltageAdapter(new Voltage220V()));
    }
}
对象适配器模式注意事项和细节
  1. 对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。根据合成复用原则,使用组合替代继承,所以它解决了类适配器必须继承src的局限性可能,也不再要求dst必须是接口。
  2. 使用成本更低,更灵活。(ps:成本的意思是侵入性更小,因为尽量使用聚合会比继承更加能够实现类之间的解耦合)

接口适配器模式

接口适配器模式介绍
  1. 一些书籍又称为:适配器模式或缺省适配器模式。
  2. 当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求。
  3. 适用于一个接口不想使用其所有的方法的情况。
接口适配器模式类图实例

在这里插入图片描述

接口适配器模式代码实例

Interface4接口

public interface Interface4 {
    public void m1();
    public void m2();
    public void m3();
    public void m4();
}

AbsAdapter抽象类对Interface4空实现。

public abstract class AbsAdapter implements Interface4 {
    @Override
    public void m1() { }

    @Override
    public void m2() { }

    @Override
    public void m3() { }

    @Override
    public void m4() {}
}

Client 类使用匿名内部类来选择实现接口中的方法。

public class Client {
    public static void main(String[] args) {
        AbsAdapter absAdapter = new AbsAdapter(){
            @Override
            public void m1(){
                System.out.println("使用了m1的方法");
            }
        };
    }
}

适配器模式在SpringMVC框架应用的源码分析

  1. SpringMvc中的HandlerAdapter,就使用了适配器模式。
  2. SpringMVC处理请求的流程
  3. 使用HandlerAdapter的原因分析;
Spring MVC的工作流程

在这里插入图片描述

适配器模式源码分析

DispatcherServlet类中的doDispatch()方法,
根据request请求得到一个Handler,这个Handler就是一个控制器。(参考下图1)
通过不同的Handler来调用相应的方法获得其所属的HandlerAdapter适配器。(参考下图2)

/**
	 * Process the actual dispatching to the handler.
	 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
	 * to find the first that supports the handler class.
	 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
	 * themselves to decide which methods are acceptable.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @throws Exception in case of any kind of processing failure
	 */
	protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
					noHandlerFound(processedRequest, response);
					return;
				}

				// Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				// Process last-modified header, if supported by the handler.
				String method = request.getMethod();
				boolean isGet = "GET".equals(method);
				if (isGet || "HEAD".equals(method)) {
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}

				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

				// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}

				applyDefaultViewName(processedRequest, mv);
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
				dispatchException = ex;
			}
			catch (Throwable err) {
				// As of 4.3, we're processing Errors thrown from handler methods as well,
				// making them available for @ExceptionHandler methods and other scenarios.
				dispatchException = new NestedServletException("Handler dispatch failed", err);
			}
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Throwable err) {
			triggerAfterCompletion(processedRequest, response, mappedHandler,
					new NestedServletException("Handler processing failed", err));
		}
		finally {
			if (asyncManager.isConcurrentHandlingStarted()) {
				// Instead of postHandle and afterCompletion
				if (mappedHandler != null) {
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
				// Clean up any resources used by a multipart request.
				if (multipartRequestParsed) {
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

在这里插入图片描述
在这里插入图片描述
追踪getHandlerAdapter()方法,其返回的是一个HandlerAdapter 接口
通过for循环来遍历所有的handlerAdapters,比对传过来的Object handler返回请求对应的HandlerAdapter.

/**
	 * Return the HandlerAdapter for this handler object.
	 * @param handler the handler object to find an adapter for
	 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
	 */
	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		if (this.handlerAdapters != null) {
			for (HandlerAdapter adapter : this.handlerAdapters) {
				if (adapter.supports(handler)) {
					return adapter;
				}
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}

追踪HandlerAdapter 接口,查看它具体的实现类有哪些.以下就是HandlerAdapter 接口的具体实现类
AbstractHandlerMethodAdapter
SimpleServletHandlerAdapter
HandlerFunctionAdapter
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
在这里插入图片描述

DispatchServlet类图实例

在这里插入图片描述

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

  1. 三种命名方式,根据src是以怎样的形式给到Adapter(在Adapter里的形式)来命名的。
  2. 三种传递方式
  • 类适配器:以类传递,在Adapter里,就是将src当做类,继承的方式。
  • 对象适配器: 以对象的方式,在Adapter里,将src作为一个对象,可以通过构造器或者setter方法的方式传入并持有。
  • 接口适配器:以接口的方式,在Adapter里,将src作为一个接口,由其子类选择进行实现。
  1. Adapter模式最大的作用还是将原本不兼容的接口融合在一起工作。
  2. 实际开发中,实现起来不拘泥于所讲解的三种经典方式。

博主感言:设计模式更多的是一个思想,而java的语言特性帮助其得到了更好的拓展和实现。

SIMATIC S7-1200, S7-1500 PID 控制[手册] 立即下载

相关推荐

RealSense D455启动教程

RealSense D455启动教程 修改rs_camera.launch

每天进步一点点 2417

设计模型之适配器模式(含UML完整实例)

设设计模型之适配器模式 1.适配器模式 1.1 定义与特点   适配器模式(Adapter)的定义如下:使用一个已经存在的类,而他的接口不符合我们的需求。这个时候我们本着开闭原则,要创建一个既符合我们需求(加入独立的或不兼容的接口功能)又实现了已存在的接口的类。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对...

atu1111的博客 9624

VMware + ubuntu20.04 + qemu安装

遇到报错可参考:(从ubuntu裸系统开始安装)

NosONE 3230

适配器模式的运用

适配器模式的运用

忆~遂愿的博客 2307

AFSim 2.9实战指南:从入门到精通的中文教程

本文是AFSim 2.9的实战中文教程,旨在帮助用户从零开始掌握这一先进的仿真框架。内容涵盖从环境安装、运行第一个“Hello World”仿真,到深入理解实体、组件、想定编辑器等核心概念,并进阶探讨动力学建模、传感器仿真与红蓝对抗想定构建。最后,指南还提供了效能分析与实战排错技巧,帮助用户将仿真结果转化为有价值的量化数据,适用于军事、航空航天等领域的复杂系统行为模拟研究。

weixin_29294395的博客 357

SC-FDMA

<br />SC-FDMA(Single-carrier Frequency-Division Multiple Access,單載波分頻多工),是LTE的上行鏈路的主流多址。<br />SC-FDMA是單波載(Single-carrier),與OFDMA相比之下具有的較低的PAPR(峰值/平均功率比,peak-to-average power ratio),比多載波的PAPR低1-3dB左右(PAPR是由于多載波在频域叠加引起)。更低的PAPR可以使行動終端(mobile terminal)在發送功效方面

jod的专栏 3299

设计模式结构型——适配器模式

适配器模式(Adapter)其别名为包装器模式(Wrapper),将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。在适配器模式中,通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器、类适配器、接口适配器三种。

tszc95的博客 3200

基于STM32的宠物智能照护嵌入式系统设计

嵌入式系统是实现物联网终端设备本地化感知、决策与执行的核心技术载体,其关键在于多传感器融合、低功耗执行控制与轻量级云边协同。本文围绕环境监测(温湿度、烟雾、余粮)、机电执行(步进电机食盘、继电器风扇)和可靠通信(MQTT+ESP8266)三大技术主线,深入解析STM32F103在资源约束下的外设调度策略、ADC采样抗干扰设计、DHT11时序精准控制及HX711称重滤波算法等工程实践要点。系统强调本地闭环优先原则,确保离线基础功能可用,同时通过阿里云IoT平台实现远程监控与告警联动,为中小型智能硬件项目提供可

weixin_29155599的博客 293

设计模式专栏——适配器模式

适配器模式(Adapter Pattern)属于结构型设计模式,也被成为Wrapper模式。将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。 适配器模式有以下两种。 类适配器模式(使用继承的适配器) 对象适配器模式(使用委托的适配器) 本节将以此展开这两种的介绍。

李秀才的博客 1099

CAN(2)-GD32

GD32中CAN的特征。

小柚子的博客 553

生成EtherCAT从站XML图片信息方法

详细介绍了EtherCAT从站XML文件中图片元素的生成方法。

kevin1499的博客 2128

Java设计模式之结构型-适配器模式(UML类图+案例分析)

将一个类的接口转换为另一个接口,使得原本由于接口不兼容的类进行兼容。适配器模式主要分为类适配器模式和对象适配器模式,前者类适配器模式之间的耦合度比后者更高,所以更推荐使用对象适配器。

黄团团的个人博客 3289

注意力机制模块:CA(坐标注意力)二次创新:融合深度可分离卷积,打造 CADS 模块

本文提出CADS模块,将坐标注意力(CA)与深度可分离卷积(DSC)深度融合,优化移动端AI部署效率。通过重构CA的计算范式,用深度卷积替代传统1×1卷积,在保持精度的同时显著降低计算开销。文章深入分析了CA的计算瓶颈和DSC的实际效率问题,详细阐述了CADS的设计原理与PyTorch实现,并提供了多组性能对比数据。该模块可直接应用于YOLO、UNet等主流模型,为移动端AI部署提供高效解决方案。

ZXSXJ的博客 96

设计模式 - 学习笔记 - 适配器模式AdapterPattern

设计模式 - 学习笔记 - 适配器模式原理分析代码演示电源插座 ElectricalSocket两口插头 PlugUSB公口手机充电器(适配器) ChargerAdapter客户端 AdapterPatternDemo 原理分析 适配器就是:扩展坞、转换器、充电头。 解决的问题就是将一个目标不支持的接口,转变成一个能用的接口。 典型场景就是功能都具备,只是接口对不上。 代码演示 电源插座 ElectricalSocket public class ElectricalSocket{ public vo

灵台方寸山斜月三星洞 606

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

设计模式学习—适配器模式(Adapter Design Pattern)

适配器模式的学习

闲鱼的博客 710

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

认真学习设计模式之适配器模式(Adapter Pattern)/包装器模式

适配器的作用可以简单通过下图得知,OO适配器就是将一个接口转换成另一个接口,以符合客户的期望。 实际场景应用可以联想插座适配器,如下图所示。 客户使用适配器的过程如下: ① 客户通过目标接口调用适配器的方法对适配器发出请求; ② 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口; ③ 客户接受到调用的结果,但并未察觉这一切是适配器在其转换作用。 ...

小小默:进无止境 2374

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

学习设计模式之适配器模式,但是宝可梦

作者在准备秋招中,学习设计模式,做点小笔记,用宝可梦为场景举例,有错误欢迎指出。

pocket_eight的博客 1000

设计模式学习--适配器模式(Adapter Pattern)+外观模式(Facade Pattern)

amp.off();各个子系统类的实现} else {} else {");可以观赏电影啦测试效果:好,关于适配器模式和外观模式就记录到这里,接下来会继续学习新的设计模式:模板方法模式。

m0_74931167的博客 331

设计模式学习笔记十一:适配器模式(Adapter Pattern)

设计模式学习笔记十一:适配器模式(Adapter Pattern)     1.概述     在软件开发中,我们经常会遇到系统间集成,在系统集成时,最常见的问题就是系统间的接口不一致。很多能够满足功能的系统模块,由于接口不一致,导致无法使用。例如,常用的媒体播放器是MS Media player和RealPlayer,他们的文件结构和软件接口完全不同,前者支持WMF格式的音频和

AlbenXie的博客 336

学习笔记【23种设计模式-第六节:Adapter Pattern适配器模式】

Adapter Pattern适配器模式 简述: 适配器模式将某个类的接口转换成客户端期望的另一个接口表示,主要目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。其别名为包装器(Wrapper)。 适配器模式属于构造型模式。 主要分为三类:适配器模式、对象适配器模式、接口适配器模式。 工作原理 适配器模式:将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容。 从用户的角度看不到被适配者,是解耦的。 用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法。 用

qq_53273362的博客 156

学习设计模式《三》——适配器模式

  适配器模式的本质是【转换匹配,复用功能】

提供C#相关开发 、云计算、运维测试、网络安全相关技术分享与服务,有意向可联系。 1199

设计模式学习笔记(3)——适配器模式(Adapter Pattern)

一、 目的:将一个类的接口转换成客户希望的另一个接口。Adapter模式使原本由于接口不兼容而不能一起工作的那些类可以一起工作。——GoF《Design Pattern》二、 描述:其实个人觉得Adapter模式在所有的模式当中算是比较简单的那种,也比较容易理解,就像我们日常生活中经常会使用USB转换器,将某种非USB接口的外设转换我们本本上

BoBo的代码世界 1186

HeadFirst 设计模式学习笔记7--适配器模式和外观模式

本文已搬家至【HeadFirst 设计模式学习笔记】7 适配器模式和外观模式

gnuhpc的专栏 2421

C#设计模式学习笔记:(6)适配器模式

本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/7640873.html,记录一下学习过程以备后续查用。 一、引言 从今天开始我们开始讲结构型设计模式,结构型设计模式有如下几种:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。 创建型设计模式解决的是对象创建的问题,而结构型设计模式解决的是类和对象组合关系的问题。 今天我们开始讲结构型设计模式里面的第一个设计模式:适配器模式。适配器模式其实很简单,在现实生活中有很多这样的实例实例:比如,手机充电

chinaherolts2008的博客 184
上一篇: 设计模式学习——建造者模式
下一篇: 设计模式学习——桥接模式
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值