此處採用了適配器模式, 因爲Controller的類型不一樣,有多重實現方式,那麼調用方式就不是肯定的,若是須要直接調用Controller方法,須要在代碼中寫成以下形式: java
if(mappedHandler.getHandler() instanceof MultiActionController){ ((MultiActionController)mappedHandler.getHandler()).xxx }else if(mappedHandler.getHandler() instanceof XXX){ ... }else if(...){ ... }
這樣假設若是咱們增長一個HardController,就要在代碼中加入一行 if(mappedHandler.getHandler() instanceof HardController)
這種形式就使得程序難以維護,也違反了設計模式中的開閉原則 -- 對擴展開放,對修改關閉。
所以Spring定義了一個適配接口,使得每一種Controller有一種對應的適配器實現類,
讓適配器代替controller執行相應的方法。這樣在擴展Controller 時,只須要增長一個適配器類就完成了SpringMVC的擴展了,真的是很精巧的作法!
廢話很少說仍是上代碼吧,爲了看得清楚,就本身實現一套代碼來模擬springMVC, 直接貼Spring源碼容易下降關注點。
spring
//定義一個Adapter接口 public interface HandlerAdapter { public boolean supports(Object handler); public void handle(Object handler); } //如下是三種Controller實現 public interface Controller { } public class HttpController implements Controller{ public void doHttpHandler(){ System.out.println("http..."); } } public class SimpleController implements Controller{ public void doSimplerHandler(){ System.out.println("simple..."); } } public class AnnotationController implements Controller{ public void doAnnotationHandler(){ System.out.println("annotation..."); } } //下面編寫適配器類 public class SimpleHandlerAdapter implements HandlerAdapter { public void handle(Object handler) { ((SimpleController)handler).doSimplerHandler(); } public boolean supports(Object handler) { return (handler instanceof SimpleController); } } public class HttpHandlerAdapter implements HandlerAdapter { public void handle(Object handler) { ((HttpController)handler).doHttpHandler(); } public boolean supports(Object handler) { return (handler instanceof HttpController); } } public class AnnotationHandlerAdapter implements HandlerAdapter { public void handle(Object handler) { ((AnnotationController)handler).doAnnotationHandler(); } public boolean supports(Object handler) { return (handler instanceof AnnotationController); } } //模擬一個DispatcherServlet import java.util.ArrayList; import java.util.List; public class DispatchServlet { public static List<HandlerAdapter> handlerAdapters = new ArrayList<HandlerAdapter>(); public DispatchServlet(){ handlerAdapters.add(new AnnotationHandlerAdapter()); handlerAdapters.add(new HttpHandlerAdapter()); handlerAdapters.add(new SimpleHandlerAdapter()); } public void doDispatch(){ //此處模擬SpringMVC從request取handler的對象,僅僅new出,能夠出, //不論實現何種Controller,適配器總能通過適配之後獲得想要的結果 // HttpController controller = new HttpController(); // AnnotationController controller = new AnnotationController(); SimpleController controller = new SimpleController(); //獲得對應適配器 HandlerAdapter adapter = getHandler(controller); //經過適配器執行對應的controller對應方法 adapter.handle(controller); } public HandlerAdapter getHandler(Controller controller){ for(HandlerAdapter adapter: this.handlerAdapters){ if(adapter.supports(controller)){ return adapter; } } return null; } public static void main(String[] args){ new DispatchServlet().doDispatch(); } }
經過這個模式能夠看出 開源代碼 中的精妙, 咱們在看框架源碼時須要有目標的看,這樣會找到不少本身須要學習的東西, 目前不少分析源碼的帖子大部分是講解what,how,
以此來拋磚引玉,但願各位可以一塊兒來討論 「why 」設計模式
轉載自:http://blog.csdn.net/w1033162186/article/details/50635348app