設計模式(五)之介面卡模式
阿新 • • 發佈:2020-08-16
時空連結:
- 所有關於設計模式的程式碼,都會託管到:設計模式程式碼,歡迎關注。
介面卡模式
概念
- 介面卡模式(Adapter Pattern)是作為兩個不相容的介面之間的橋樑。這種型別的設計模式屬於結構模式,它結合了兩個獨立介面的功能。
- 這種模式涉及到一個單一的類,該類負責加入獨立的或者不相容的介面功能。
- 它將一個系統的介面轉換成另外一種形式,從而使原來不能直接呼叫的介面變的可以呼叫。
特點
- 源(Adaptee):需要被適配的物件或型別,舊版本或者是記憶體卡和筆記本之間的讀卡器。
- 介面卡(Adapter):連線目標和源的中間物件,相當於一個轉換器,新舊版本可以實現相容。
- 目標(Target):客戶所期待的介面。目標可以使具體的或抽象的類,也可以是介面。
使用場景
新老版本介面的相容。
優缺點
-
優點
- 可以讓任何兩個沒有關聯的類一起遠行。
- 提高了類的複用。
- 增加了類的透明度。
- 靈活性好。
-
缺點
- 過多的使用介面卡,會讓系統非常零亂,不易整體把握。
模式的結構
SpringMvc是一個非常棒的框架,配置相對靈活,實現簡單。今天我們就模擬一個有關介面卡的適配過程和簡單使用。
開發步驟
- 模擬SpringMvc的DispatcherServlet物件,對請求進行派發。我們也編寫一個和它一樣的doService方法,如下圖:
在該方法內部,呼叫 doDispatch方法
從所有的介面卡物件當中挑選出唯一一個對應此請求handler的介面卡
getHandlerAdapter方法內部,呼叫介面卡中的supports方法,判斷是否支援請求handler
大致有哪些HandlerAdapter呢?
我們上面有見到有一個supports方法,介面卡的方法是定義在一個統一的父類當中的,主要包含兩個方法,supports判斷是否支援對應的handler請求,
handle則是處理具體的handler請求,那讓我們來看看,如下圖:
到這裡也看到其實並不難實現。下面我們就開始吧。
定義一個類似於DispatcherServlet的處理類
package com.lee.adapter.controller;
import com.lee.adapter.service.HandlerAdapter;
import com.lee.adapter.service.impl.RequestMappingHandlerAdapter;
import com.lee.adapter.service.impl.SimpleHandlerAdapter;
import com.lee.adapter.service.impl.SimpleServletHandlerAdapter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author zfl_a
* @Desc 入口測試
* @date 2020/8/16
* @project springboot_design_pattern
*/
@RestController
public class DispatcherController implements InitializingBean {
//自動裝配
@Autowired
private Map<String,Controller> controllerMap = new HashMap<>();
private List<HandlerAdapter> handlerAdapters = new ArrayList<>();
/**
* 處理
* @param controllerName simpleController simpleServletController httpRequestController
* @return
*/
@GetMapping("/doService")
public String doService(String controllerName){
return doDispatcher(controllerName);
}
private String doDispatcher(String controllerName) {
// 獲取介面卡 引數可根據具體的Handler替換
Controller controller = controllerMap.get(controllerName);
HandlerAdapter ha = getHandlerAdapter(controller);
if(ha == null) {
return "沒有此介面卡";
}
//具體處理
return ha.handle(controller);
}
/**
* 獲取介面卡
* @param controller
* @return
*/
private HandlerAdapter getHandlerAdapter(Controller controller) {
if (this.handlerAdapters != null) {
for (HandlerAdapter ha : this.handlerAdapters) {
if (ha.supports(controller)) {
return ha;
}
}
}
return null ;
}
@Override
public void afterPropertiesSet() throws Exception {
//初始化介面卡例項
RequestMappingHandlerAdapter mappingHandlerAdapter = new RequestMappingHandlerAdapter();
SimpleHandlerAdapter simpleHandlerAdapter = new SimpleHandlerAdapter();
SimpleServletHandlerAdapter servletHandlerAdapter = new SimpleServletHandlerAdapter();
handlerAdapters.add(mappingHandlerAdapter);
handlerAdapters.add(simpleHandlerAdapter);
handlerAdapters.add(servletHandlerAdapter);
}
}
- 模擬Controller請求類
定義一個共同的Controller,什麼也不做
package com.lee.adapter.controller;
/**
* @author zfl_a
* @date 2020/8/16
* @project springboot_design_pattern
*/
public interface Controller {
}
定義對應的實現類,做具體處理的
package com.lee.adapter.controller;
import org.springframework.stereotype.Component;
/**
* @author zfl_a
* @date 2020/8/16
* @project springboot_design_pattern
*/
@Component
public class HttpRequestController implements Controller {
public String doRequestMapping(){
return "do http request ....";
}
}
package com.lee.adapter.controller;
import org.springframework.stereotype.Component;
/**
* @author zfl_a
* @date 2020/8/16
* @project springboot_design_pattern
*/
@Component
public class SimpleController implements Controller {
public String doSimple(){
return "do simple ....";
}
}
package com.lee.adapter.controller;
import org.springframework.stereotype.Component;
/**
* @author zfl_a
* @date 2020/8/16
* @project springboot_design_pattern
*/
@Component
public class SimpleServletController implements Controller {
public String doSimpleServlet(){
return "do Simple Servlet....";
}
}
- 定義一個和HandlerAdapter的介面卡介面
package com.lee.adapter.service;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author zfl_a
* @Desc 所有介面卡的父類
* @date 2020/8/16
* @project springboot_design_pattern
*/
public interface HandlerAdapter {
boolean supports(Object handler);
String handle(Object handler) ;
}
- 定義和上面Controller對應的Adapter
package com.lee.adapter.service.impl;
import com.lee.adapter.controller.HttpRequestController;
import com.lee.adapter.service.HandlerAdapter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
/**
* @author zfl_a
* @date 2020/8/16
* @project springboot_design_pattern
*/
public class RequestMappingHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof HttpRequestController;
}
@Override
public String handle(Object handler) {
return ((HttpRequestController)handler).doRequestMapping();
}
}
package com.lee.adapter.service.impl;
import com.lee.adapter.controller.SimpleController;
import com.lee.adapter.service.HandlerAdapter;
import org.springframework.stereotype.Component;
/**
* @author zfl_a
* @date 2020/8/16
* @project springboot_design_pattern
*/
public class SimpleHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof SimpleController;
}
@Override
public String handle(Object handler) {
return ((SimpleController)handler).doSimple();
}
}
package com.lee.adapter.service.impl;
import com.lee.adapter.controller.SimpleServletController;
import com.lee.adapter.service.HandlerAdapter;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
/**
* @author zfl_a
* @date 2020/8/16
* @project springboot_design_pattern
*/
public class SimpleServletHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return handler instanceof SimpleServletController;
}
@Override
public String handle(Object handler) {
return ((SimpleServletController)handler).doSimpleServlet();
}
}
測試結果如下:
-
當請求引數為 ?controllerName=simpleServletController時:
-
當請求引數為 ?controllerName=httpRequestController時: