最近開始在研讀這本 manning 出的 Struts 2 in Action
由於先前已經有 Struts 1 的實務經驗,所以在念這本書的期間確實觀念上要上手快很多。
一開始我以為 Struts 2 是相容於 Struts 1 的,結果完全不是這麼回事,Struts 由第一代進步到第二代,老實說,只有名字跟 design pattern 與名字有傳承而已。看到這裡,很多人心都涼了~我也是,我以為有相容,並且有提供更好的 components support。不過沒關係,基本上想法還是差不了太遠(就我目前 survey 三分之一的感觸),基本上還是以 MCV 架構為主。
所謂 MVC 就是 Model-View-Controller 的縮寫,也就是 separate of concern的概念,MCV 架構的宗旨就是希望將程式開發團隊區分成兩部分,一部分是專門負責 view 端,也就是使用者介面端的設計;另一部分就是專門撰寫程式中核心的 business logic 元件,也就是 model 端。那你一定會問,controller 誰來寫勒? 這就是牽涉到上面所說的兩隊人馬必須要協調的事項,model 端的人要與 view 端的人協調關於哪些 business logic 的結果要放到哪個 UI 上作顯示的動作。所以 controller 算是整個系統中的中樞,所以在 MVC 架構中,由 controller 為 entry point,並且決定哪個動作需要執行哪些 models 與呼叫哪些 views 來顯示。
回到主題,Struts 2 這次的開發團隊,拋棄了原先 Struts 1 的設計想法,採用 OpenSymphony 的 WebWork framework 為基礎架構。引進一些新的想法來降低 coupling 與提高 cohesion (註),像是 interceptor 就是一個很好的例子。往後我會慢慢的將這本書中我所讀到的、有感觸的部分依照各章節來說明。
下圖一是 Struts 1 的架構圖。
圖一 Struts 1 架構圖
圖一的流程:
1. 首先使用者會透過 browser 向 web server 的 controller 發出 request。
2. controller 就是一個 programmer 撰寫一個 class extends Action 的程式,該程式會根據使用者的請求到 Model 端的 DataObject 要求資料,這裡的 DataObject 我是意旨負責與資料庫取資料或是負責 business logic 的 class。
3. DataObject 會到 Database 中取得相關的資料。
4. DataObject 將結果回傳給 Controller。
5. Controller 根據資料選擇某個 View 來顯示給使用者。
6. 使用者透過 browser 看到一個經過處理後的頁面,並且將頁面要求的資料填入,可能是一個 form 的表單。
7. Struts framework 會將頁面上的資料帶到 Model 端的 Form,這裡的 Form 是一個 class extends ActionForm 的程式。
8. Struts framework 會將此 Model 的 Form 交給 Controller,接下來就是重複 2~4 的動作來完成另一次的 request。
下圖二則是 Struts 2 的架構圖,這張圖示依照這本書上的圖來重新繪製的。
圖二 Struts 2 架構
圖二的流程:
1. 同圖一,使用者下 request 給 Controller,此時的 Controller 不同於 Struts 1 的自己撰寫,而是 Struts 2 framework 來 support。
2. Controller 根據 configuration 檔案的描述來呼叫對應的 Model 的 Action 物件。
3. Model 端的 Action 物件會包含 data 與 business logic,這點與 Struts 1 就有很大的差別。簡而言之,Struts 2 的 Action 就是結合了 Struts 1 的 Controller 與 Form 物件。
4. 接著 Action 會決定要顯示哪個頁面。
5. 頁面將 Action 中的 data 排列在頁面上後顯示給使用者。
在此,就可以看出來 Struts 1,2 之間的最明顯差異性,Struts 2 將資料的存放與 business logic 合併在一起。不過這只是其中一點的差異。
註:Coupling and Cohesion
Coupling 就是指 classes 之間的相依性,若相依性越高,代表要使用此 class 需要其他 class support 就越多,這樣此 class 的 reuse 就越不易,所以我們希望程式中的 coupling 要越低越好,也就是此 class 知道別的 classes 的資訊越少越好。
Cohesion 是指單一 class 中的功能單純度,也就是說此 class 功能越單純,相對的 class 中的 fields 之間的凝聚力越高,因為每一個 fields 的設立都是為了完成某一項功能而產生的,所以凝聚力會越高。若是一個 class 擁有的能力越不單純,他的凝聚力就會越低。例如:class Person 中提供了計算某人的薪資與計算某人的年齡,所以 Person 中會有兩個 fields:salary 與 birthday,但是因為計算薪資與計算年齡之間並沒有任何的關聯,所以 salary 與 birthday 就沒有任何的凝聚力,所以這樣的設計是不好的。