本文源碼:GitHub·點這裡 || GitEE·點這裡
一、擴充卡模式簡介
1、基礎概念
擴充卡模式把一個類的接口變換成用戶端所期待的另一種接口,進而使原本因接口不比對而無法在一起工作的兩個類能夠在一起工作。擴充卡模式有類擴充卡模式和對象擴充卡模式,以及預設(接口)擴充卡,三種不同的形式。
2、生活場景
基于擴充卡模式,把220V的電壓,轉換為需要的110V電壓。
public class C01_InScene {
public static void main(String[] args) {
CurrentAdapter adapter = new CurrentAdapter() ;
System.out.println(adapter.get110VCurrent()) ;
}
}
// 220V電流
class Current220V {
public int get220VCurrent (){
return 220 ;
}
}
// 110V電流接口
interface Current110V {
int get110VCurrent () ;
}
// 電流擴充卡
class CurrentAdapter extends Current220V implements Current110V {
// 電流轉換方法
@Override
public int get110VCurrent() {
int high = get220VCurrent() ;
int low = high/2 ;
return low ;
}
}
二、類擴充卡
1、模式簡介
類的擴充卡模式把适配的類的API轉換成為目标類的API。

2、核心角色
- 目标(Target)角色
這就是所期待得到的接口。
- 源(Adapee)角色:
現在需要适配的接口。
- 擴充卡(Adaper)角色
擴充卡類是本模式的核心。擴充卡把源接口轉換成目标接口。
3、源碼實作
interface Target {
void sampleOperation1();
void sampleOperation2();
}
class Adaptee {
public void sampleOperation1(){
System.out.println("Adaptee.sampleOperation1()");
}
}
class Adapter extends Adaptee implements Target{
@Override
public void sampleOperation2() {
System.out.println("Adapter.sampleOperation2()");
}
}
三、對象擴充卡
與類的擴充卡模式一樣,對象的擴充卡模式把被适配的類的API轉換成為目标類的API,與類的擴充卡模式不同的是,對象的擴充卡模式不是使用繼承關系連接配接到Adaptee類,而是使用委派關系連接配接到Adaptee類。
2、源碼實作
interface Target1 {
void sampleOperation1();
void sampleOperation2();
}
class Adaptee1 {
public void sampleOperation1(){
System.out.println("Adaptee.sampleOperation1()");
}
}
class Adapter1 implements Target1 {
private Adaptee1 adaptee ;
public Adapter1 (Adaptee1 adaptee){
this.adaptee = adaptee;
}
public void sampleOperation1() {
this.adaptee.sampleOperation1();
}
@Override
public void sampleOperation2() {
System.out.println("Adapter.sampleOperation2()");
}
}
四、接口擴充卡
預設(接口)适配(Default Adapter)模式為一個接口提供預設實作,這樣子類型可以從這個預設實作進行擴充,而不必從原有接口進行擴充。
2、源代碼實作
public class C04_AdapterInte {
public static void main(String[] args) {
ServiceAdapter adapter = new ServiceAdapter(){
@Override
public int serviceOperation2() {
return 22 ;
}
};
System.out.println(adapter.serviceOperation2());
}
}
interface AbstractService {
void serviceOperation1();
int serviceOperation2();
String serviceOperation3();
}
class ServiceAdapter implements AbstractService{
@Override
public void serviceOperation1() {
}
@Override
public int serviceOperation2() {
return 0;
}
@Override
public String serviceOperation3() {
return null;
}
}
五、Spring架構應用
1、應用場景描述
在SpringMvc執行控制執行請求的時候,有這樣一個流程
1)前段控制器DispatcherServlet調用處理器擴充卡去執行Handler(也就是Controller);
2)處理器擴充卡去執行Handler,給擴充卡傳回ModelAndView ;
3)處理器擴充卡向前端控制器傳回ModelAndView ;
2、流程分析
- 核心接口和實作
Controller和HandlerAdapter兩核心接口。
- HandlerAdapter
擴充卡接口,使Handler有對應的擴充卡實作類,擴充卡代替Handler(控制層Controller)執行相應的方法。
public interface HandlerAdapter {
// 判斷類型是否比對
boolean supports(Object var1);
// 執行方法,傳回ModelAndView
ModelAndView handle(HttpServletRequest var1,
HttpServletResponse var2, Object var3)
throws Exception;
}
supports()方法傳入處理器,判斷擴充卡是否支援,如果支援則傳回支援的擴充卡實作類。
- DispatchServlert
抽取源碼中展現流程的幾個步驟。
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
mappedHandler = this.getHandler(processedRequest);
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
- SimpleControllerHandlerAdapter
最後看下supports和handle兩個方法的具體實作。
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
public SimpleControllerHandlerAdapter() {
}
public boolean supports(Object handler) {
return handler instanceof Controller;
}
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response, Object handler)
throws Exception {
return ((Controller)handler).handleRequest(request, response);
}
}
六、擴充卡優缺點
1、優點分析
更好的複用性,系統需要使用現有的類,而此類的接口不符合系統的需要。那麼通過擴充卡模式就可以讓這些功能得到更好的複用。更好的擴充性。
2、缺點分析
過多的使用擴充卡,會讓系統非常零亂,不易整體進行把控。
七、源代碼位址
GitHub·位址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·位址
https://gitee.com/cicadasmile/model-arithmetic-parent