Java描述设计模式(07):适配器模式
本文源码:GitHub·点这里 || GitEE·点这里
一、适配器模式简介
1、基础概念
适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。适配器模式有类适配器模式和对象适配器模式,以及缺省(接口)适配器,三种不同的形式。
2、生活场景
基于适配器模式,把220V的电压,转换为需要的110V电压。
public class C01_InScene { public static void main(String[] args) { CurrentAdapter adapter = new CurrentAdapter() ; System.out.println(adapter.get110VCurrent()) ; } } // 220V电流 class Current220V { public int get220VCurrent (){ return 220 ; } } // 110V电流接口 interface Current110V { int get110VCurrent () ; } // 电流适配器 class CurrentAdapter extends Current220V implements Current110V { // 电流转换方法 @Override public int get110VCurrent() { int high = get220VCurrent() ; int low = high/2 ; return low ; } }
二、类适配器
1、模式简介
类的适配器模式把适配的类的API转换成为目标类的API。
2、核心角色
- 目标(Target)角色
这就是所期待得到的接口。
- 源(Adapee)角色:
现在需要适配的接口。
- 适配器(Adaper)角色
适配器类是本模式的核心。适配器把源接口转换成目标接口。
3、源码实现
interface Target { void sampleOperation1(); void sampleOperation2(); } class Adaptee { public void sampleOperation1(){ System.out.println("Adaptee.sampleOperation1()"); } } class Adapter extends Adaptee implements Target{ @Override public void sampleOperation2() { System.out.println("Adapter.sampleOperation2()"); } }
三、对象适配器
1、模式简介
与类的适配器模式一样,对象的适配器模式把被适配的类的API转换成为目标类的API,与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用委派关系连接到Adaptee类。
2、源码实现
interface Target1 { void sampleOperation1(); void sampleOperation2(); } class Adaptee1 { public void sampleOperation1(){ System.out.println("Adaptee.sampleOperation1()"); } } class Adapter1 implements Target1 { private Adaptee1 adaptee ; public Adapter1 (Adaptee1 adaptee){ this.adaptee = adaptee; } public void sampleOperation1() { this.adaptee.sampleOperation1(); } @Override public void sampleOperation2() { System.out.println("Adapter.sampleOperation2()"); } }
四、接口适配器
1、模式简介
缺省(接口)适配(Default Adapter)模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。
2、源代码实现
public class C04_AdapterInte { public static void main(String[] args) { ServiceAdapter adapter = new ServiceAdapter(){ @Override public int serviceOperation2() { return 22 ; } }; System.out.println(adapter.serviceOperation2()); } } interface AbstractService { void serviceOperation1(); int serviceOperation2(); String serviceOperation3(); } class ServiceAdapter implements AbstractService{ @Override public void serviceOperation1() { } @Override public int serviceOperation2() { return 0; } @Override public String serviceOperation3() { return null; } }
五、Spring框架应用
1、应用场景描述
在SpringMvc执行控制执行请求的时候,有这样一个流程
1)前段控制器DispatcherServlet调用处理器适配器去执行Handler(也就是Controller);
2)处理器适配器去执行Handler,给适配器返回ModelAndView ;
3)处理器适配器向前端控制器返回ModelAndView ;
2、流程分析
- 核心接口和实现
Controller和HandlerAdapter两核心接口。
- HandlerAdapter
适配器接口,使Handler有对应的适配器实现类,适配器代替Handler(控制层Controller)执行相应的方法。
public interface HandlerAdapter { // 判断类型是否匹配 boolean supports(Object var1); // 执行方法,返回ModelAndView ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception; }
supports()方法传入处理器,判断适配器是否支持,如果支持则返回支持的适配器实现类。
- DispatchServlert
抽取源码中体现流程的几个步骤。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HandlerExecutionChain mappedHandler = null; mappedHandler = this.getHandler(processedRequest); HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler()); mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); mappedHandler.applyPostHandle(processedRequest, response, mv); }
- SimpleControllerHandlerAdapter
最后看下supports和handle两个方法的具体实现。
public class SimpleControllerHandlerAdapter implements HandlerAdapter { public SimpleControllerHandlerAdapter() { } public boolean supports(Object handler) { return handler instanceof Controller; } public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return ((Controller)handler).handleRequest(request, response); } }
六、适配器优缺点
1、优点分析
更好的复用性,系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。更好的扩展性。
2、缺点分析
过多的使用适配器,会让系统非常零乱,不易整体进行把控。
七、源代码地址
GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
源码分析 RocketMQ DLedger(多副本) 之日志追加流程
上一篇我们详细分析了源码分析 RocketMQ DLedger 多副本之 Leader 选主,本文将详细分析日志复制的实现。 根据 raft 协议可知,当整个集群完成 Leader 选主后,集群中的主节点就可以接受客户端的请求,而集群中的从节点只负责从主节点同步数据,而不会处理读写请求,与M-S结构的读写分离有着巨大的区别。 有了前篇文章的基础,本文将直接从 Leader 处理客户端请求入口开始,其入口为:DLedgerServer 的 handleAppend 方法开始讲起。 1、日志复制基本流程 在正式分析 RocketMQ DLedger 多副本复制之前,我们首先来了解客户端发送日志的请求协议字段,其类图如下所示:我们先一一介绍各个字段的含义: String group该集群所属组名。 String remoteId请求目的节点ID。 String localId节点ID。 int code请求响应字段,表示返回响应码。 String leaderId = null集群中的Leader Id。 long term集群当前的选举轮次。 byte[] body待发送的数据。 日志的请...
- 下一篇
前端进阶|第十天 数组分组编程,区间还是连续一网打尽
先看题面: 随机生成一个长度为 10 的整数类型的数组,例如 [2, 10, 3, 4, 5, 11, 10, 11, 20],将其排列成一个新数组,要求新数组形式如下,例如 [[2, 3, 4, 5], [10, 11], [20]]。 看完有点懵,根据他举的例子,数组被分为了三个子数组,但分类的依据却有两种理解,1.按照区间划分,即0-9,10-19,20-29等等,依此类推,以10为阶梯进行分组。2.按照连续区间划分,大小连续的分为一组。 嗯,到底出题人咋想的,不得而知。so 管他呢,写就完了。 我们先按照第一种理解: // IIFE 生成随机数组 var arr = (function (len) { let temp = [] for (var i = 0; i < len; i++) { temp.push(Math.floor(Math.random() * 100)); } return temp; })(10) console.log(arr); //1.排序 重写sort 排序 arr.sort((a, b) => { return a - b }) c...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Mario游戏-低调大师作品
- CentOS6,CentOS7官方镜像安装Oracle11G
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Windows10,CentOS7,CentOS8安装Nodejs环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8编译安装MySQL8.0.19
- MySQL8.0.19开启GTID主从同步CentOS8