你还不懂设计模式? - 适配器设计模式

适配器设计模式(Adapter Pattern),顾名思义。创建一个类的适配器使之能够满足原本不兼容的接口需求。

适配器模式中两个重要角色:Adaptee(被适配者) , Adapter(适配者) ,Target(适配的接口或者类)

实现适配器模式方式主要有以下两种:

  1. 委托方式,
    结构图如下:
    在这里插入图片描述

  2. 继承模式

结构图如下:
在这里插入图片描述

这里推荐使用方式1

经典问题,给手机充电。 我国民用标准电压为220V(交流电) , 手机充电只需要5V(直流电) .因此就需要一个充电器(适配器)来做电流和电压的转换。

在Java代码中可以这样实现:
① 创建被适配器(220V交流电)。

public class Electricity220 {
    public double outPut(){
        return 220;
    }
}

② 创建手机充电接口 target

public interface TelPhoneInterface {
     double charge5();
}

③ 创建手机充电适配器 adapter

public class TelPhoneAdapter implements TelPhoneInterface {
    private Electricity220 electricity220 ;

    public TelPhoneAdapter(Electricity220 electricity220) {
        this.electricity220 = electricity220;
    }

    @Override
    public double charge5() {
        return electricity220.outPut()/44;
    }
}

测试代码:

 public static void main(String[] args) {
     double adapterElectricity = new TelPhoneAdapter(new Electricity220()).charge5();
     System.out.println(adapterElectricity);
 }
输出结果: 5.0 

这个有点类似与装饰者模式,他们的区别是:适配器模式用于填补不同接口之间的差异。装饰者模式则是不改变接口。

适配器设计模式在spring源码中也有很多应用。比较经典的是spring MVC 中的HandlerAdapter 。

public interface HandlerAdapter {
    //判断这个适配器是否能适配这个给定handler对象
	boolean supports(Object handler);
	
	@Nullable
	ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

	long getLastModified(HttpServletRequest request, Object handler);

}

在这里插入图片描述

在DispatcherServlet中的使用如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		...
		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.
				//根据对应请求的handler来获取对应的适配器
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
				...
				// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

	            ...
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}catch (Exception ex) {...}
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {}finally {}
	}
	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#supports就相当判断请求对应的handler应该用那个HandlerAdapter来拆箱。HandlerAdapter#handle才是真正的适配接口。

实际项目中,要尽量提前设计好接口。不到不得已建议不要使用适配器模式,容易增加代码的复杂程度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值