专门做折扣的网站有哪些,openshift安装wordpress密码忘记,做 视频在线观看网站,广告制作费#x1f4e2; 大家好#xff0c;我是 【战神刘玉栋】#xff0c;有10多年的研发经验#xff0c;致力于前后端技术栈的知识沉淀和传播。 #x1f497; #x1f33b; CSDN入驻不久#xff0c;希望大家多多支持#xff0c;后续会继续提升文章质量#xff0c;绝不滥竽充数… 大家好我是 【战神刘玉栋】有10多年的研发经验致力于前后端技术栈的知识沉淀和传播。 CSDN入驻不久希望大家多多支持后续会继续提升文章质量绝不滥竽充数欢迎多多交流。 文章目录 写在前面的话基础介绍代码实现Spring 中的适配器模式适配器VS装饰者适配器实操补充总结陈词 写在前面的话
本篇文章继续介绍一下适配器模式单词为Adapter。日常生活中适配器的场景也随处可见例如USB、插座等转换头或电压转换处理总之起中转适配作用的都可以考虑用适配器模式。
工作中的场景就更不用说了新老服务之间中转的桥梁、服务、工具都可以称之为Adapter那这个适配器模式到底是什么样的且听我娓娓道来。
相关文章 《程序猿之设计模式实战 · 策略模式》 《程序猿之设计模式实战 · 装饰者模式》 《程序猿之设计模式实战 · 池化思想》 《程序猿之设计模式实战 · 观察者模式》 《程序猿之设计模式实战 · 责任链模式》 《程序猿之设计模式实战 · 模板方法》 基础介绍
基础概念
适配器模式Adapter Pattern是一种结构型设计模式它允许将一个接口转换成客户端所期望的另一个接口。
适配器模式使得原本由于接口不兼容而无法一起工作的类可以一起工作。
主要组成
适配器模式通常由以下几个角色组成
目标接口Target客户端所期望的接口。源类Adaptee需要被适配的类通常是一个已有的类。适配器Adapter实现目标接口并持有源类的实例负责将源类的接口转换为目标接口。
使用场景
当你希望使用一些现有的类但它们的接口与您所需要的接口不兼容时。当你希望创建一个可重用的类它可以与一些不相关的类即接口不兼容的类一起工作时。当你希望通过多个类的组合来实现某个功能而这些类的接口不一致时。
总结一下
适配器模式通过将不兼容的接口进行适配使得不同的类可以协同工作。在 Spring 框架中适配器模式的应用使得不同类型的处理器和视图能够以统一的方式进行处理从而提高了系统的灵活性和可扩展性。 代码实现
挺简单的一段示例也是对原有类的增强使之可以间接成为目标接口。
// 目标接口
interface Target {void request();
}// 源类
class Adaptee {public void specificRequest() {System.out.println(Called specificRequest());}
}// 适配器
class Adapter implements Target {private Adaptee adaptee;public Adapter(Adaptee adaptee) {this.adaptee adaptee;}Overridepublic void request() {// 调用源类的方法adaptee.specificRequest();}
}// 客户端代码
public class Client {public static void main(String[] args) {Adaptee adaptee new Adaptee();Target target new Adapter(adaptee);target.request(); // 输出: Called specificRequest()}
}Spring 中的适配器模式
在 Spring 框架中适配器模式被广泛应用于多个地方尤其是在 MVC 模块中。以下是一些主要的应用场景
1、HandlerMappingSpring MVC 中的 HandlerMapping 使用适配器模式来将请求映射到处理器Controller。不同类型的处理器如注解驱动的控制器、传统的控制器等可以通过适配器进行统一处理。
2、HandlerAdapterSpring MVC 中的 HandlerAdapter 是适配器的具体实现它允许不同类型的处理器如 SimpleControllerHandlerAdapter、AnnotationMethodHandlerAdapter 等以统一的方式处理请求。
3、ViewResolver在视图解析过程中Spring 使用适配器模式来支持不同类型的视图如 JSP、Thymeleaf 等。
以HandlerMapping为例是如何利用到适配器模式
在 Spring 框架中HandlerMapping 是一个重要的组件它负责将 HTTP 请求映射到相应的处理器Handler。为了实现这一点Spring 使用了适配器模式来处理不同类型的请求处理器如控制器。
适配器模式在 HandlerMapping 中的应用步骤如下
1、接口与实现
在 Spring 中HandlerMapping 会将请求映射到一个处理器Handler而这个处理器可能是不同类型的对象比如
控制器类例如使用 Controller 注解的类函数式处理器例如使用 RequestMapping 注解的方法
为了能够处理这些不同类型的处理器Spring 使用了适配器模式。
2、适配器接口
Spring 定义了一个适配器接口例如 HandlerAdapter它为不同类型的处理器提供了统一的调用方式。这个接口定义了一个方法比如 handle()用于处理请求。
public interface HandlerAdapter {boolean supports(Object handler);ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}3、具体适配器
Spring 提供了多个具体的适配器实现例如
RequestMappingHandlerAdapter用于处理使用 RequestMapping 注解的控制器方法。
SimpleControllerHandlerAdapter用于处理实现了 Controller 接口的传统控制器。
每个适配器实现了 HandlerAdapter 接口并提供了对特定类型处理器的支持。
public class RequestMappingHandlerAdapter implements HandlerAdapter {Overridepublic boolean supports(Object handler) {return (handler instanceof RequestMappingHandler);}Overridepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 处理请求}
}4、HandlerMapping 的工作流程
请求到达当一个 HTTP 请求到达时HandlerMapping 会根据请求的 URL 找到对应的处理器。
适配器选择HandlerMapping 会遍历所有注册的 HandlerAdapter找到一个支持找到的处理器的适配器。
请求处理一旦找到合适的适配器HandlerMapping 会调用适配器的 handle() 方法传递请求和响应对象以及处理器。
返回结果适配器处理请求并返回结果如 ModelAndView最终将响应返回给客户端。
总结一下通过适配器模式Spring 能够灵活地支持多种类型的请求处理器而不需要在 HandlerMapping 中硬编码每种处理器的处理逻辑。这种设计使得框架具有良好的扩展性和可维护性允许开发者轻松添加新的处理器类型和适配器。 适配器VS装饰者
观察了示例代码可以发现和装饰者模式有点像都是扩展增强了原有对象那两者有什么区别呢
适配器模式和装饰者模式虽然在结构上有相似之处但它们的目的和使用场景是不同的下面是它们的主要区别
1、先看适配器模式
1目的接口转换适配器模式的主要目的是将一个类的接口转换为客户端所期望的另一个接口。它使得原本由于接口不兼容而无法一起工作的类可以一起工作。
2使用场景当你希望使用一些现有的类但它们的接口与您所需要的接口不兼容时。例如将一个旧的 API 适配到新的接口以便可以在新的系统中使用。
3结构适配器通常包含一个源类的实例并实现目标接口。适配器负责将目标接口的方法调用转发到源类的方法。
2、再看装饰者模式
1、目的功能扩展装饰者模式的主要目的是在不改变对象自身的情况下动态地为对象添加额外的功能。它允许在运行时对对象进行扩展。
2、使用场景当你希望在不修改现有类的情况下给对象添加新的行为或功能时。例如为一个图形对象添加边框、阴影等装饰效果。
3、结构装饰者通常包含一个被装饰对象的实例并实现与被装饰对象相同的接口。装饰者可以在调用被装饰对象的方法之前或之后添加额外的行为。
3、总结一下
适配器模式关注于接口的转换使得不兼容的接口可以协同工作。
装饰者模式关注于功能的扩展通过组合的方式为对象添加新的行为。
【代理、桥接、装饰器、适配器的区别】
代理模式代理模式在不改变原始类接口的条件下为原始类定义一个代理类主要目的是控制访问而非加强功能这是它跟装饰器模式最大的不同。桥接模式桥接模式的目的是将接口部分和实现部分分离而让它们可以较为容易、独立地加以改变。装饰器模式装饰器模式在不改变原始类接口的情况下对原始类功能进行增强并且支持多个装饰器的嵌套使用。适配器模式适配器模式是一种时候的补救策略适配器提供跟原始类不同的接口而代理模式、装饰器模式提供的都是跟原来类相同的接口。 适配器实操补充
经典案例一 // 类适配器: 基于继承
// 自己扩展的客户端期望得到的接口里面还可以包含被适配者没有的接口
public interface ITarget {void f1();void f2();void fc();
}//被适配者外部系统
//理解为外国的电源插座这些方法不会暴露给客户端直接调用因此不支持或者说不好用
public class Adaptee {public void fa() { //... }public void fb() { //... }public void fc() { //... }
}//适配器类用于替换被适配者完成功能
//理解为转接头负责两个事情提供方法给客户端调用方法内部会调用目标国外电源插座的方法
public class Adaptor extends Adaptee implements ITarget {public void f1() {super.fa();}public void f2() {//...重新实现f2()...}// 这里fc()不需要实现直接继承自Adaptee这是跟对象适配器最大的不同点
}// 对象适配器基于组合
public interface ITarget {void f1();void f2();void fc();
}public class Adaptee {public void fa() { //... }public void fb() { //... }public void fc() { //... }
}public class Adaptor implements ITarget {private Adaptee adaptee;public Adaptor(Adaptee adaptee) {this.adaptee adaptee;}public void f1() {adaptee.fa(); //委托给Adaptee}public void f2() {//...重新实现f2()...}public void fc() {adaptee.fc();}
}经典案例二类适配器模式 在上图中可以看出Adaptee类被适配者、外国插座并没有sampleOperation2()方法而客户端则期待这个方法。为使客户端能够使用 Adaptee 类提供一个中间环节即类 Adapter适配器、转换头把 Adaptee 的 API与 Target 类的API衔接起来。Adapter 与 Adaptee 是继承关系这决定了这个适配器模式是类的
模式所涉及的角色有
1、目标(Target)角色这就是所期待得到的接口。
2、源(Adapee)角色现在需要适配的接口。
3、适配器(Adaper)角色适配器类是本模式的核心。适配器把源接口转换成目标接口。显然这一角色不可以是接口而必须是具体类。
public interface Target {/*** 这是源类Adaptee也有的方法*/public void sampleOperation1(); /*** 这是源类Adapteee没有的方法*/public void sampleOperation2();
}//上面给出的是目标角色的源代码这个角色是以一个JAVA接口的形式实现的。
//可以看出这个接口声明了两个方法sampleOperation1()和sampleOperation2()。
//而源角色Adaptee是一个具体类它有一个sampleOperation1()方法但是没有sampleOperation2()方法。
public class Adaptee {public void sampleOperation1(){}
}//适配器角色Adapter扩展了Adaptee,同时又实现了目标(Target)接口。由于Adaptee没有提供sampleOperation2()方法而目标接口又要求这个方法
//因此适配器角色Adapter实现了这个方法。
public class Adapter extends Adaptee implements Target {/*** 由于源类Adaptee没有方法sampleOperation2()* 因此适配器补充上这个方法*/Overridepublic void sampleOperation2() {//写相关的代码}}经典案例三对象适配器模式
与类的适配器模式一样对象的适配器模式把被适配的类的API转换成为目标类的API与类的适配器模式不同的是对象的适配器模式不是使用继承关系连接到Adaptee类而是使用委派关系连接到Adaptee类。 PS其实基本一样就是继承改为组合。 从上图可以看出Adaptee类并没有sampleOperation2()方法而客户端则期待这个方法。为使客户端能够使用Adaptee类需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系这决定了适配器模式是对象的。
public interface Target {/*** 这是源类Adaptee也有的方法*/public void sampleOperation1(); /*** 这是源类Adapteee没有的方法*/public void sampleOperation2();
}public class Adaptee {public void sampleOperation1(){}
}public class Adapter {private Adaptee adaptee;public Adapter(Adaptee adaptee){this.adaptee adaptee;}/*** 源类Adaptee有方法sampleOperation1* 因此适配器类直接委派即可*/public void sampleOperation1(){this.adaptee.sampleOperation1();}/*** 源类Adaptee没有方法sampleOperation2* 因此由适配器类需要补充此方法*/public void sampleOperation2(){//写相关的代码}
}总结陈词
怎么说呢适配器模式还是很强大的它为我们带来
1、更好的复用性系统需要使用现有的类而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
2、更好的扩展性在实现适配器功能的时候可以调用自己开发的功能从而自然地扩展系统的功能。
但它也有一些缺点过多的使用适配器会让系统非常零乱不易整体进行把握。比如明明看到调用的是A接口其实内部被适配成了B接口的实现一个系统如果太多出现这种情况无异于一场灾难。因此如果不是很有必要可以不使用适配器而是直接对系统进行重构。
最终是否采用还是根据实际情况决定纸上得来终觉浅绝知此事要躬行。 后续会逐步分享企业实际开发中的实战经验有需要交流的可以联系博主。