1
)
MVC
模式
當(dāng)年做
JSP
生產(chǎn)實(shí)習(xí)時(shí),印象最深也最困惑的模式就是
MVC
模式了。那時(shí)候
Struts
剛紅,幾乎每本
Struts
書(shū)中都會(huì)有大篇幅的
MVC
介紹。這個(gè)模式最早出現(xiàn)在
GUI
,后來(lái)在
Web
服務(wù)器端紅火起來(lái),先前在
Ajax
書(shū)中也看到
Web
客戶(hù)端的
MVC
介紹。說(shuō)實(shí)話(huà),在我看了很多人的
MVC
解釋后,我仍有些糊涂,這里說(shuō)說(shuō)我的理解。
有人提到MVC模式時(shí)說(shuō)MVC代表了模型層、視圖層、控制層,我覺(jué)得這是不對(duì)的。在經(jīng)典的J2EE三層架構(gòu)中,三層是分為Web層、業(yè)務(wù)層、持久化層;這個(gè)經(jīng)典分層是基于分布式應(yīng)用(EJB)的,也就說(shuō),Web層物理上是在Web服務(wù)器中,
業(yè)務(wù)層和持久化層物理上是在應(yīng)用服務(wù)器中。在這種情況下,MVC只是屬于Web層這一層的,而不是分為三層。在這種分布式應(yīng)用中,視圖就是JSP(如果采用的話(huà)),控制器就是Servlet(如果采用的話(huà)),而模型就是就是調(diào)用業(yè)務(wù)層的在Web層中的樁子。假如我們采用輕量級(jí)的SSH技術(shù)架構(gòu),視圖還是JSP,控制器是Struts,而模型就是Spring+Hibernate。這里最難理解的就是模型的概念。我覺(jué)得模型是有狀態(tài)和行為的,那么Struts中的Action調(diào)用的Servcie方法就是模型的行為,而返回給JSP的DTO(DO)就是模型的狀態(tài)。
2
)頁(yè)面控制器
對(duì)于一個(gè)頁(yè)面請(qǐng)求,總要有個(gè)地方負(fù)責(zé)處理和頁(yè)面跳轉(zhuǎn)的地方,這個(gè)地方就是頁(yè)面控制器。頁(yè)面控制器有兩種,一種是如Servlet的腳本文件,一種是如JSP的服務(wù)器頁(yè)面。對(duì)于Java來(lái)說(shuō),JSP就是只應(yīng)該用來(lái)顯示動(dòng)態(tài)的或靜態(tài)的信息,而不是用來(lái)負(fù)責(zé)處理Request并Redirect頁(yè)面,否則Servlet就要失業(yè)了。盡管一個(gè)Web程序可以全由JSP文件組成,但將控制甚至業(yè)務(wù)腳本雜亂的穿插在Tag中真的是太糟糕的實(shí)踐了。我記得最初學(xué)JSP時(shí),從網(wǎng)上得到的用JSP做的管理系統(tǒng)很多都是純JSP,那時(shí)我還以為那就是Java
Web開(kāi)發(fā)的最佳實(shí)踐了!
3
)前端控制器
如果你不是Web框架的設(shè)計(jì)者,想必你不會(huì)有機(jī)會(huì)做個(gè)前端控制器,尤其是在擁有了大量?jī)?yōu)秀的Web框架的Java社區(qū)里。前端控制器這個(gè)模式我以前在《J2EE核心模式》中看到過(guò),感覺(jué)那本書(shū)的例子寫(xiě)的很好。前端控制器是由一個(gè)Web處理程序和一個(gè)命令(Conmmand)層次結(jié)構(gòu)組成。以Struts1為例,其前端控制器就是ActionServlet,那些我們需要編寫(xiě)的Action就是前端控制器要處理的命令。在簡(jiǎn)化Web開(kāi)發(fā)方面,前端控制器通過(guò)Web處理程序做一些具有共性的有價(jià)值的事情。比如Struts1的前端控制器通過(guò)Form簡(jiǎn)化了請(qǐng)求參數(shù)的獲取和驗(yàn)證,而Struts2(WebWork)做的就更多,它的命令Action不是單例的,Action的屬性可以是封裝了請(qǐng)求參數(shù)的(經(jīng)過(guò)類(lèi)型轉(zhuǎn)換)域?qū)ο蠡騻鬏攲?duì)象,其以攔截器鏈表現(xiàn)的Web
AOP更是簡(jiǎn)化了橫切性方面的操作。
4
)模板視圖
Java
Web
中最常用的視圖表現(xiàn)技術(shù)就是
JSP
,我們可以以多種編程手法表現(xiàn)來(lái)自于數(shù)據(jù)庫(kù)中的數(shù)據(jù)。我們可以使用
Scriptlet
將模型數(shù)據(jù)嵌在
HTML
中間,我們可以使用諸如
JSTL
和框架標(biāo)簽穿插在
HTML
中間,我們也可以自定義標(biāo)簽來(lái)封裝一類(lèi)數(shù)據(jù)表現(xiàn)。相比來(lái)說(shuō),使用標(biāo)簽要比
Scriptlet
更清晰些,畢竟
JSP
頁(yè)面就是應(yīng)該編寫(xiě)可視化更好的標(biāo)簽。但如果有條件判斷等邏輯信息,使用標(biāo)簽有時(shí)也不見(jiàn)得有多清晰,這是可以考慮使用自定義標(biāo)簽。
5
)轉(zhuǎn)換視圖
MF
通過(guò)
XSLT
介紹了轉(zhuǎn)換視圖,由于本人沒(méi)有使用過(guò)
XSLT
,這里不做介紹。我倒想起了以前的
Ajax
編程,也是個(gè)轉(zhuǎn)換視圖的過(guò)程。在
Servlet
中將模型數(shù)據(jù)拼串成
XML
(
HTML
)文檔,然后傳送到
JS
,再構(gòu)造成
DOM
樹(shù)(或是將
HTML
文檔添充在指定的
HTML
標(biāo)簽內(nèi))。在最原始的
Ajax
編程中,無(wú)論是在
Servlet
中拼串還是在
JS
中構(gòu)造
DOM
樹(shù)都是很繁瑣很難調(diào)試的事情,尤其是在我很不喜歡在
Java
文件中夾雜著
Tag
信息的情況下。
6
)兩步視圖
兩步視圖說(shuō)的是,用兩個(gè)步驟把領(lǐng)域數(shù)據(jù)轉(zhuǎn)換成
HTML
:第一步形成某種邏輯頁(yè)面,第二步把這些邏輯頁(yè)面轉(zhuǎn)換成
HTML
頁(yè)面。這個(gè)模式實(shí)際上一種裝飾者模式,第二步的視圖渲染過(guò)程要做的就是將邏輯視圖加上一致的表現(xiàn)形式。我能想到的是,可以通過(guò)諸如
SiteMesh
、
Tiles
等工具完成兩步視圖模式。在不使用
XSLT
的情況下,第一步形成的模板視圖顯然也不是一種諸如
XML
的邏輯頁(yè)面
。
7
)應(yīng)用控制器
這是《
POEAA
》
Web
表現(xiàn)模式中的最后一個(gè)模式,
MF
說(shuō)這個(gè)模式很少會(huì)被用到,它一般用在具有特定的視圖導(dǎo)航的情況下,也就是說(shuō)頁(yè)面訪問(wèn)順序不是任意的而是和當(dāng)時(shí)的對(duì)象狀態(tài)有關(guān)。書(shū)中介紹的例子是關(guān)于狀態(tài)模型的,沒(méi)完全理解的說(shuō)。我能想到的例子是具有上下步的注冊(cè)過(guò)程,可以認(rèn)為上下步的切換是特定的,是具有狀態(tài)信息的;可以強(qiáng)聯(lián)系上
MF
的說(shuō)法,一個(gè)輸入控制器將請(qǐng)求傳到應(yīng)用控制器,應(yīng)用控制器根據(jù)當(dāng)前步數(shù)和請(qǐng)求的步數(shù)使用特定的命令進(jìn)行操作,并傳回輸入控制器下一步的視圖。關(guān)于應(yīng)用控制器的更精確的理解,也歡迎明白的你指出。
注:此文系重溫《企業(yè)應(yīng)用架構(gòu)模式》一書(shū)的簡(jiǎn)要筆記,對(duì)企業(yè)應(yīng)用架構(gòu)模式或
Web
表現(xiàn)模式感興趣的朋友可以閱讀一下該書(shū)。