設計自己的MVC框架
取這樣一個標題太大,吸引眼球嘛@_@。
事實是最近讀《J2EE設計模式》講述表達層模式的那幾章,書中有一個前端控製器+command模式的workflow例子,就琢磨著可以很簡單地擴展成一個MVC框架。花了一個下午改寫了下,對書中所述的理解更為深入。我想這也許對於學習和理解設計模式,以及初次接觸struts等MVC框架的人可能有點幫助。因為整個模型類似於struts,我把它取名叫strutslet^_^
(一)完整的類圖如下:
1。前端控製器(FrontController):前端控製器提供了一個統一的位置來封裝公共請求處理,它的任務相當簡單,執行公共的任務,然後把請求轉交給相應的控製器。在strutslet中,前端控製器主要作用也在於此,它初始化並解析配置文件,接受每個請求,並簡單地把請求委托給調度器(Dispatcher),由調度器執行相應的動作(Action)。調度器把action返回的url返回給FrontController, FrontController負責轉發。
2。Action接口:command模式很好的例子,它是一個命令接口,每一個實現了此接口的action都封裝了某一個請求:新增一條數據記錄並更新model,或者把某個文件寫入磁盤。命令解耦了發送者和接受者之間聯係。發送者調用一個操作,接受者接受請求執行相應的動作,因為使用Command模式解耦,發送者無需知道接受者任何接口。
3。Dispatcher:調度器,負責流程的轉發,負責調用action去執行業務邏輯。由調度器選擇頁麵和action,它去除了應用行為和前端控製器間的耦合。調度器服務於前端控製器,它把model的更新委托給action,又提供頁麵選擇給FrontController
4。ActionForward:封裝了轉向操作所需要信息的一個模型,包括name和轉向url
5。ActionModel:解析配置文件後,將每一個Action封裝成一個ActionModel對象,所有ActionModel構成一個map,並存儲在ServletContext中,供整個框架使用。
(二)源代碼分析:
1。Action接口,隻有一個execute方法,任何一個action都隻要實現此接口,並實現相應的業務邏輯,最後返回一個ActionForward,提供給Dispacher調用。

















比如,我們要實現一個登陸係統,LoginAction驗證用戶名和密碼,如果正確,返回success頁麵,如果登陸失敗,返回fail頁麵:

























2。還是先來看下兩個模型:ActionForward和ActionModel,沒什麼東西,屬性以及相應的getter,setter方法:


































































3。知道了兩個模型是什麼樣,也應該可以猜到我們的配置文件大概是什麼樣的了,與struts的配置文件格式類似:








path是在應用中將被調用的路徑,class指定了調用的哪個action,forward元素指定了轉向,比如我們這裏如果是success就轉向hello.jsp,失敗的話轉向fail.jsp,這裏配置了demo用到的LoginAction。
4。Dispacher接口,主要是getNextPage方法,此方法負責獲得下一個頁麵將導向哪裏,提供給前端控製器轉發。


















5。原先書中實現了一個WorkFlow的Dispatcher,按照順序調用action,實現工作流調用。而我們所需要的是根據請求的path 調用相應的action,執行action的execute方法返回一個ActionForward,然後得到ActionForward的 viewUrl,將此viewUrl提供給前端控製器轉發,看看它的getNextPage方法:






























6。前端控製器(FrontController),它的任務我們已經很清楚,初始化配置文件;存儲所有action到 ServletContext供整個框架使用;得到發起請求的path,提供給Dispachter查找相應的action;調用Dispatcher,執行getNextPage方法得到下一個頁麵的url並轉發:






































doGet()和doPost方法我們都讓它調用process方法:



























7。最後,web.xml的配置就非常簡單了,配置前端控製器,提供啟動參數(配置文件所在位置,為空就查找/WEB-INF/下麵的strutslet-config.xml文件),我們把所有以action結尾的請求都交給FrontController處理:















最後更新:2017-05-17 00:48:09