手机网站制作费用多少,wordpress 检索文件夹,免费行情软件app大全,网络规划设计师自学引言
在软件开发中#xff0c;经常会遇到不同接口之间的兼容性问题。当需要使用一个已有的类#xff0c;但其接口与我们所需的不兼容时#xff0c;我们可以通过适配器模式来解决这一问题。适配器模式是一种结构型设计模式#xff0c;它允许接口不兼容的类之间进行合作。本…引言
在软件开发中经常会遇到不同接口之间的兼容性问题。当需要使用一个已有的类但其接口与我们所需的不兼容时我们可以通过适配器模式来解决这一问题。适配器模式是一种结构型设计模式它允许接口不兼容的类之间进行合作。本文将深入探讨适配器模式的概念、应用场景以及在Java中的实现方式。
一、理解适配器模式
1.1 什么是适配器模式
适配器模式是一种结构型设计模式旨在将一个类的接口转换为另一个类的接口以使原本不兼容的类能够一起工作。适配器模式通常涉及一个适配器类该类充当两个不兼容接口之间的桥梁使得它们可以相互协作。
1.2 适配器模式的角色
在适配器模式中通常有以下几个角色
目标接口Target定义客户端使用的特定领域接口。适配器Adapter实现目标接口并包装一个或多个不兼容的类以使其与客户端一起工作。被适配者Adaptee拥有需要被适配的接口但与目标接口不兼容。
二、适配器模式的应用场景
2.1 与现有代码的集成
当我们需要在现有代码基础上添加新的功能或组件时通常会遇到新旧代码之间接口不兼容的情况。此时适配器模式可以帮助我们将新组件与现有代码进行无缝集成而无需修改已有的代码。
2.2 复用现有功能
有时我们可能会有一些功能强大但接口不兼容的类库而我们希望利用这些功能来实现自己的需求。适配器模式可以将这些现有类库包装在一个适配器中以便我们可以轻松地在自己的项目中复用这些功能。
三、Java 中的适配器模式实现
在Java中适配器模式常见的实现方式包括类适配器和对象适配器两种。
3.1 类适配器
类适配器通过继承被适配者类并实现目标接口来实现适配器。下面是一个简单的示例
// 目标接口
interface Target {void request();
}// 被适配者
class Adaptee {void specificRequest() {System.out.println(Adaptees specific request);}
}// 类适配器
class Adapter extends Adaptee implements Target {Overridepublic void request() {specificRequest();}
}3.2 对象适配器
对象适配器通过将被适配者对象作为适配器的一个成员变量来实现适配器。下面是一个简单的示例
// 对象适配器
class Adapter implements Target {private Adaptee adaptee;Adapter(Adaptee adaptee) {this.adaptee adaptee;}Overridepublic void request() {adaptee.specificRequest();}
}3.3 基于对象适配器实现一个真实的案例
拿我身边的事物举例我有一个 mac 笔记本电脑现在我想拓展一个显示器但是我买的显示器提供的接口仅支持 HDMI 接口而我的电脑上并不支持这个接口怎么办呢这时候拓展坞就出现了它将显示器和笔记本电脑连接在了一起实现了显示器拓展屏的功能。场景如下图所示 这就是一个典型的适配器模式场景我们来看下职责划分
type-c 接口就是目标接口拓展坞 就是适配器HDMI 接口就是被适配器
总体就是 HDMI 接口通过拓展坞适配成了 type-c 接口插入电脑使用。我们来看下代码实现
拓展坞及其支持的插槽
package com.markus.desgin.mode.structural.adapter;import static com.markus.desgin.mode.structural.adapter.ComputerSlot.HDMI;
import static com.markus.desgin.mode.structural.adapter.ComputerSlot.USB;public class ComputerAdapter implements AdvancedComputerSlot {ComputerSlot usb new USBSlot();ComputerSlot hdmi new HDMISlot();public ComputerAdapter() {}Overridepublic void typeC(String type) {switch (type) {case HDMI:hdmi.hdmi();break;case USB:usb.usb();break;default:throw new UnsupportedOperationException(拓展坞中没有该类型的数据插槽!);}}
}public interface ComputerSlot {String HDMI HDMI;String USB USB;void hdmi();void usb();String type();
}public class HDMISlot implements ComputerSlot {Overridepublic void hdmi() {System.out.println(数据线插入 HDMI 接口成功);}Overridepublic void usb() {throw new UnsupportedOperationException(该数据线不允许插入当前插槽);}Overridepublic String type() {return HDMI;}
}public class USBSlot implements ComputerSlot {Overridepublic void hdmi() {throw new UnsupportedOperationException(该数据线不允许插入当前插槽);}Overridepublic void usb() {System.out.println(数据线插入 USB 接口成功);}Overridepublic String type() {return USB;}
}
目标接口
public interface AdvancedComputerSlot {String TYPEC TYPE-C;void typeC(String type);
}public class AdvancedComputerSlotImpl implements AdvancedComputerSlot {ComputerAdapter adapter new ComputerAdapter();Overridepublic void typeC(String type) {switch (type) {case ComputerSlot.HDMI:case ComputerSlot.USB:adapter.typeC(type);break;case TYPEC:System.out.println(Type-C 接口插入成功!);break;default:throw new UnsupportedOperationException(暂时不支持插入其他类型);}}
}客户端
public class AdapterPatternDemo {public static void main(String[] args) {AdvancedComputerSlot advancedComputerSlot new AdvancedComputerSlotImpl();advancedComputerSlot.typeC(TYPEC);advancedComputerSlot.typeC(HDMI);advancedComputerSlot.typeC(USB);}
}四、适配器模式在 Spring 框架中的使用
4.1 org.springframework.web.servlet.HandlerAdapter
在 Spring MVC 中HandlerAdapter 负责将请求分发给相应的处理器Handler。不同类型的处理器可能具有不同的接口而 HandlerAdapter 则负责将不同类型的处理器适配为统一的处理器接口从而实现请求的统一处理。
我们来看下 HandlerAdapter 的接口设计以及部分实现类:
public interface HandlerAdapter {/*** Given a handler instance, return whether this {code HandlerAdapter}* can support it. Typical HandlerAdapters will base the decision on the handler* type. HandlerAdapters will usually only support one handler type each.* pA typical implementation:* p{code* return (handler instanceof MyHandler);* }* param handler the handler object to check* return whether this object can use the given handler*/boolean supports(Object handler);/*** Use the given handler to handle this request.* The workflow that is required may vary widely.* param request current HTTP request* param response current HTTP response* param handler the handler to use. This object must have previously been passed* to the {code supports} method of this interface, which must have* returned {code true}.* return a ModelAndView object with the name of the view and the required* model data, or {code null} if the request has been handled directly* throws Exception in case of errors*/NullableModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;/*** Same contract as for HttpServlets {code getLastModified} method.* Can simply return -1 if theres no support in the handler class.* param request current HTTP request* param handler the handler to use* return the lastModified value for the given handler* deprecated as of 5.3.9 along with* {link org.springframework.web.servlet.mvc.LastModified}.*/Deprecatedlong getLastModified(HttpServletRequest request, Object handler);}public class HttpRequestHandlerAdapter implements HandlerAdapter {Overridepublic boolean supports(Object handler) {return (handler instanceof HttpRequestHandler);}OverrideNullablepublic ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {((HttpRequestHandler) handler).handleRequest(request, response);return null;}OverrideSuppressWarnings(deprecation)public long getLastModified(HttpServletRequest request, Object handler) {if (handler instanceof LastModified) {return ((LastModified) handler).getLastModified(request);}return -1L;}}4.2 org.springframework.aop.framework.adapter.AdvisorAdapter
它是 Spring AOP 框架中的一个重要组件将不同类型的 Advisor 适配成统一的 MethodInterceptorAdvice的工具。在 Spring AOP 中Advisor 是将通知应用到切点上的对象而 MethodInterceptor 是实际执行通知逻辑的对象。
Spring AOP 将不同类型的通知Before、After、Around、Throws 等转换为相应的 Advisor并将其适配到切点上。在运行时每个 Advisor 都被转换为一个 MethodInterceptor并应用于目标方法的执行。
我们也来看下它的相关接口定义和部分实现
public interface AdvisorAdapter {/*** Does this adapter understand this advice object? Is it valid to* invoke the {code getInterceptors} method with an Advisor that* contains this advice as an argument?* param advice an Advice such as a BeforeAdvice* return whether this adapter understands the given advice object* see #getInterceptor(org.springframework.aop.Advisor)* see org.springframework.aop.BeforeAdvice*/boolean supportsAdvice(Advice advice);/*** Return an AOP Alliance MethodInterceptor exposing the behavior of* the given advice to an interception-based AOP framework.* pDont worry about any Pointcut contained in the Advisor;* the AOP framework will take care of checking the pointcut.* param advisor the Advisor. The supportsAdvice() method must have* returned true on this object* return an AOP Alliance interceptor for this Advisor. Theres* no need to cache instances for efficiency, as the AOP framework* caches advice chains.*/MethodInterceptor getInterceptor(Advisor advisor);}class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {Overridepublic boolean supportsAdvice(Advice advice) {return (advice instanceof MethodBeforeAdvice);}Overridepublic MethodInterceptor getInterceptor(Advisor advisor) {MethodBeforeAdvice advice (MethodBeforeAdvice) advisor.getAdvice();return new MethodBeforeAdviceInterceptor(advice);}}五、设计模式百宝箱 在本节我们开始填充我们的百宝箱 面向对象基础 抽象封装多态继承 面向对象原则 依赖抽象不要依赖具体类针对接口编程不针对具体实现编程类应该对扩展开放对修改关闭为交互对象之间的松耦合设计而努力多用组合少用继承尽管有类适配器的实现方式多数情况下我们都是使用的对象适配器 面向对象设计模式 简单工厂模式定义了一个创建对象的接口将创建对象的内容从客户端抽离出来抽象工厂模式提供一个接口用于创建相关或依赖对象的家族而不需要明确指定具体类原型模式通过复制现有对象来创建新对象提高代码效率和可维护性建造者模式将一个复杂对象的构建过程与其表示分离使得同样的构建过程可以创建不同的表示适配器模式将一个类的接口转换成客户期望的另一个接口。适配器让原来接口不兼容的类可以合作无间
六、总结
本文深入探讨了适配器模式的概念、应用场景以及在 Java 中的实现方式。首先介绍了适配器模式的基本概念包括目标接口、适配器和被适配者等角色。然后通过示例演示了类适配器和对象适配器两种实现方式并以一个真实场景的例子说明了适配器模式的具体应用。
在介绍了适配器模式的基本概念和实现方式后文章进一步探讨了适配器模式在 Spring 框架中的应用。通过分析 org.springframework.web.servlet.HandlerAdapter 和 org.springframework.aop.framework.adapter.AdvisorAdapter 这两个类的设计和实现展示了适配器模式在 Spring 框架中的重要作用。
适配器模式是一种非常常用且灵活的设计模式在实际开发中经常能够见到其身影。通过本文的介绍读者可以更深入地理解适配器模式的作用及其在实际项目中的应用为日后的软件设计和开发提供参考和借鉴。