适配器模式(Adapter)/ 变压器模式

本文深入探讨适配器模式的概念,包括类适配器和对象适配器,以及其在SpringAOP和SpringMVC中的应用。通过实例展示如何解决接口不兼容的问题,提高代码复用性和扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


将类的接口转化为客户期望的另一个接口,使原本不兼容的类可以一起工作,解决兼容问题。
符合开闭原则,只需要新增,无需修改原来的代码。

适用场景

  1. 类已存在,但与需求不匹配
  2. Spring aop 、SpringMvc - handleAdapter

优点:

  1. 复用现有类,且不需改变

类适配器

类结构图

在这里插入图片描述
Target(目标抽象类):定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。
Adaptee(原角色类):被适配的角色,它定义了一个已经存在的接口,这个接口需要适配。
Adapter(适配器类):适配器作为一个转换器,对Adaptee和Target进行适配。

原有的实现

public class Adaptee {
   public void adapteeRequest() {
      System.out.println("被适配者的方法");
   }
}

定义一个接口Target

public interface Target {
   void request();
}

实现接口,并继承原有的实现,以达到适配器的效果

public class Adapter extends Adaptee implements Target{
   @Override
   public void request() {
      //...一些操作...
      super.adapteeRequest();
      //...一些操作...
   }
}

缺点:

  1. Adapter 作为adapterTarget子类,对外同时暴露了request()、adapteeReques(),违背最少知道原则。

对象适配模式

持有适配者的对象引用

类结构图

在这里插入图片描述

适配器类 持有 原有类的对象引用

public class Adapter implements Target{
   
   private Adaptee adaptee = new Adaptee();	//适配者是对象适配器的一个属性

   @Override
   public void request() {
      //...
      adaptee.adapteeRequest();
      //...
   }
}

源码中的适配器模式

SpringAOP

AdvisorAdapter有3个实现,MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter。
Spring根据不同的AOP配置来使用对应的advice。

AdvisorAdapter.class

public interface AdvisorAdapter {
    boolean supportsAdvice(Advice var1);

    MethodInterceptor getInterceptor(Advisor var1);
}

MethodBeforeAdviceAdapter.class

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
    MethodBeforeAdviceAdapter() {
    }

    public boolean supportsAdvice(Advice advice) {
        return advice instanceof MethodBeforeAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
}

MethodBeforeAdviceAdapter作为适配器类,将原有的 MethodBeforeAdvice 替换成 MethodBeforeAdviceInterceptor。

SpringMVC

DispatcherSevlet.doDispatch方法中调用的this.getHandlerAdapter方法。

	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		if (this.handlerAdapters != null) {
			for (HandlerAdapter ha : this.handlerAdapters) {
				if (logger.isTraceEnabled()) {
					logger.trace("Testing handler adapter [" + ha + "]");
				}
				if (ha.supports(handler)) {
					return ha;
				}
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}

handler是原有的类,HandlerAdapter接口的实现类HttpRequestHandlerAdapter 作为其适配器类。

HandlerAdapter 接口

public interface HandlerAdapter {

	 */
	boolean supports(Object handler);

	@Nullable
	ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

	long getLastModified(HttpServletRequest request, Object handler);

}

适配器 HttpRequestHandlerAdapter

public class HttpRequestHandlerAdapter implements HandlerAdapter {

	@Override
	public boolean supports(Object handler) {
		return (handler instanceof HttpRequestHandler);
	}

	@Override
	@Nullable
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		((HttpRequestHandler) handler).handleRequest(request, response);
		return null;
	}

	@Override
	public long getLastModified(HttpServletRequest request, Object handler) {
		if (handler instanceof LastModified) {
			return ((LastModified) handler).getLastModified(request);
		}
		return -1L;
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值