作者:江南白衣 

    Struts與Webwork的扇子請(qǐng)?zhí)^本篇。

    MVC不就是把M、V、C分開么?至唯物樸素的做法是兩個(gè)JSP一個(gè)負(fù)責(zé)View,一個(gè)負(fù)責(zé)Controller,再加一個(gè)負(fù)責(zé)Model的Java Bean,已經(jīng)可以工作得很好,那時(shí)候一切都很簡(jiǎn)單。
    而現(xiàn)在為了一些不是本質(zhì)的功能,冒出這么多非標(biāo)準(zhǔn)的Web框架,實(shí)在讓人一陣郁悶。像Ruby On Rails那樣簡(jiǎn)捷開發(fā),可用可不用,而且沒有太多的限制需要學(xué)習(xí)的,比如Webwork這型還可以考慮。但像Struts那樣越用框架越麻煩,或者像Tapestry那樣有嚴(yán)重自閉傾向,額上鑿著"高手專用玩具"的,用在團(tuán)隊(duì)里就是不負(fù)責(zé)任的行為了。

    so,我的MVC方案是使用Spring MVC的Controller接口,寫最普通的JavaBean作為Controller,本質(zhì)就和當(dāng)年拿JSP作Controller差不多,但擁有了Spring IOC的特性。
    之所以用這么消極的選擇標(biāo)準(zhǔn),是因?yàn)橛X得這一代MVC框架離重回RAD時(shí)代的標(biāo)準(zhǔn)還很遠(yuǎn),注定了只是一段短暫的,過渡的技術(shù),不值得投資太多精力和團(tuán)隊(duì)學(xué)習(xí)成本。

1. 原理
     Spring MVC按植物分類學(xué)屬于Martin Flower〈企業(yè)應(yīng)用模式〉里的靜態(tài)配置型Front Controler,使用DispatchServlet截獲所有*.do的請(qǐng)求,按照xml文件的配置,調(diào)用對(duì)應(yīng)的Command對(duì)象的handleRequest(request,response)函數(shù),同時(shí)進(jìn)行依賴對(duì)象的注入。
     我們的Controller層,就是實(shí)現(xiàn)handleRequest(request,response)函數(shù)的普通JavaBean。

2. 優(yōu)勢(shì)
    
Spring MVC與struts相比的優(yōu)勢(shì):
     一是它的Controller有著從松到緊的類層次結(jié)構(gòu),用戶可以選擇實(shí)現(xiàn)只有一個(gè)HandleRequest()函數(shù)的接口,也可以使用它有很多回調(diào)函數(shù)的SimpleFormController類。
     二是不需要Form Bean,也不需要Tapestry那所謂面向?qū)ο蟮捻撁鎸?duì)象,對(duì)于深怕類膨脹,改一個(gè)東西要?jiǎng)覰個(gè)地方的人最適合不過。
     三是不需要強(qiáng)XML配置文件,宣告式編程是好的,但如果強(qiáng)制成框架,什么都要在xml里面宣告,寫的時(shí)候繁瑣,看的時(shí)候也要代碼配置兩邊看才能明白就比較麻煩了。
 
     那Webwork呢?沒有實(shí)戰(zhàn)過,不過因?yàn)閷?duì)MVC框架所求就不多,單用Spring MVC的Controller已經(jīng)可以滿足需求,就不多搞一套Webwork來給團(tuán)隊(duì)設(shè)坎,還有給日后維護(hù),spring,ww2之間的版本升級(jí)添麻煩了。真有什么需要添加的,Spring MVC源代碼量很少,很容易掌控和擴(kuò)展。
 
3.化簡(jiǎn)
3.1. 直接implement Controller,實(shí)現(xiàn)handleRequest()函數(shù)
      首先,simple form controller非我所好,一點(diǎn)都不simple。所以有時(shí)我會(huì)直接implement Controller接口。這個(gè)接口的唯一函數(shù)是供Front Controller調(diào)用的handleRequest(request,response)。
      如果需要application對(duì)象,比如想用application.getRealPath()時(shí),就要extends webApplicationObjectSupport。

3.2.每個(gè)Controler負(fù)責(zé)一組相關(guān)的action
       我是堅(jiān)決支持一個(gè)Controler負(fù)責(zé)多個(gè)action的,一個(gè)Controler一個(gè)action就像一個(gè)function一個(gè)類一樣無聊。所以我用最傳統(tǒng)的方式,用URL參數(shù)如msg="insert"把一組相關(guān)action交給一個(gè)Controler控制。ROR與制作中的Groovy On Rails都是這種模式,Spring也有MultiActionController支持。
       以上三者都是把URL參數(shù)直接反射為Controller的函數(shù),而Stripes的設(shè)計(jì)可用annotation標(biāo)注url action到響應(yīng)函數(shù)的映射。
      
3.3.xml宣告式編程的取舍 
    我的取舍很簡(jiǎn)單,反正Spring沒有任何強(qiáng)制,我只在可能需要不重新編譯而改變某些東西的時(shí)候,才把東西放在xml里動(dòng)態(tài)注入。jsp路徑之類的就統(tǒng)統(tǒng)收回到controller里面定義.
 
3.4.Data Binder
       Data Binder是Controller的必有環(huán)節(jié),對(duì)于Spring提供的DataBinder,照理完全可用,唯一不爽是對(duì)象如果有內(nèi)嵌對(duì)象,如訂單對(duì)象里面包含了Customer對(duì)象,Spring需要你先自行創(chuàng)建了Customer對(duì)象并把它賦給了Order對(duì)象,才可能實(shí)現(xiàn)order.customer.customer_no這樣的綁定。我偷懶,又拿Jakarta BeanUtils出來自己做了一個(gè)Binder。

3.5.提取基類
      最后還是忍不住提取了一個(gè)基類,負(fù)責(zé)MultiAction和其他一些簡(jiǎn)便的方法。Sprnig的MultiActionController做得太死,規(guī)定所有函數(shù)的第1,2個(gè)參數(shù)必須是request和response,不懂動(dòng)態(tài)的,溫柔的進(jìn)行參數(shù)注入。

      
      經(jīng)過化簡(jiǎn)再化簡(jiǎn),已經(jīng)是很簡(jiǎn)單一個(gè)Java Bean ,任誰都可以輕松上手,即使某年某月技術(shù)的大潮把現(xiàn)在所有MVC框架都淹沒了,也不至于沒人識(shí)得維護(hù)。

相關(guān)文章
簡(jiǎn)化Spring(1)--配置文件
簡(jiǎn)化Spring(2)--Model層
簡(jiǎn)化Spring(3)--Controller層
簡(jiǎn)化Spring(4)--View層