最近有些朋友一直在問我關於 Smart Framework 中 MVC 的問題,爲什麼和傳統的 MVC 不一樣?在傳統的 MVC 中,由 Controller 接收請求,將數據封裝爲 Model 的形式,並將其傳入 View 中。
可見,Model 是由 Controller 推送到 View 上的,不妨稱它爲“正向 MVC”,它是一種“推模式(Push Pattern)”。
與其相反,就有“反向 MVC”,它是一種“拉模式(Pull Pattern)”。
可見,Model 是由 View 從 Controller 中拉過去的。Smart Framework 目前就是選擇的這種“反向 MVC”模式。直接在 HTML(也就是View)中發送 AJAX 請求,該請求由 Action(也就是 Controller)接收,隨後將數據模型轉爲 JSON 格式返回到 HTML 中。
對於大多數用戶而言,“反向 MVC”似乎有些彆扭,但它確實有其價值。著名的 Ext JS 框架就推薦使用這種“反向 MVC”,因爲所有的請求都由 View 來發出,響應也由 View 來渲染。可見,“反向 MVC”是實現富客戶端 Web 應用程序的利器!
Push |
Pull |
Controller解釋用戶行爲,產生相應的data並推送到View上 |
假設用戶需要某種輸出,因此View去訪問Controller,拿到所需data後呈現給用戶 |
適用於執行(用戶)行爲和任務 e.g. 添加用戶評價 |
適用於響應顯示data的需求 e.g. 顯示客戶信息及購物清單 |
通常涉及一個Controller及對應的View |
通常涉及一個View和多個Controller |
推送專門爲某個View的data e.g. JSP中用tag取得data |
推送各個View都可以用的data e.g. JSP中從Context中取得data |
更好地分離View |
分離View做的不太好 |
由於 Smart Framework 是一款易用的輕量級 Java Web 框架,卻不能實現傳統的“正向 MVC”,這豈不是有些說不過去了?也不符合大衆胃口啊!
所有非常有必要對 MVC 框架進行擴展,同時滿足“正向 MVC”與“反向 MVC”。
經與網友們溝通,現得出以下幾種方案,用一個 Action 代碼示例來說明這一切:
方案一
@Request("get:/foo") public Page index() { String aaa = "aaa"; String bbb = "bbb"; String ccc = "ccc"; return new Page("foo.jsp") .data("aaa", aaa) .data("bbb", bbb) .data("ccc", ccc); }
該 Action 方法返回一個 Page 對象,在 return 語句中創建 Page 對象,在構造器中傳入 View,並通過一系列的 data() 鏈式方法傳遞 Model。
方案二
@Request("get:/foo") public Page index() { String aaa = "aaa"; String bbb = "bbb"; String ccc = "ccc"; Map<String, Object> data = new HashMap<String, Object>(); data.put("aaa", aaa); data.put("bbb", bbb); data.put("ccc", ccc); return new Page("foo.jsp", data); }
首先構造一個 Map<String, Object>,用於封裝 Model,最後返回 Page 對象,在構造器同時傳入 View 與 Model。
方案三
@Request("get:/foo") public Page index() { String aaa = "aaa"; String bbb = "bbb"; String ccc = "ccc"; return new Page("foo.jsp", "aaa", aaa, "bbb", bbb, "ccc", ccc ); }
返回 Page 對象,無需構造 Map 與調用鏈式 data() 方法,第一個參數爲 View,隨後採用動態參數(Object …)方式,傳入 Model 的 key-value 對,基數表示 key,偶數表示 value。
方案四
@Request("get:/foo") public String index(Model model) { String aaa = "aaa"; String bbb = "bbb"; String ccc = "ccc"; model.put("aaa", aaa); model.put("bbb", bbb); model.put("ccc", ccc); return "foo.jsp"; }
不再返回 Page 對象,而是返回一個 String 類型的 View,將 Model 對象通過參數傳遞進來(其實就是一個 Map),並通過 put() 方法初始化 Model。注意:此時無需將 Model 返回,因爲它是由框架進行管理的。
對於以上三種方案,均有利弊,還請廣大網友提供進行評判,或給出更好的方案。期待您的反饋!
轉載:http://www.kankanews.com/ICkengine/archives/62597.shtml