最近有些朋友一直在问我关于 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