两种 MVC 模式

原创
2013/10/17 21:53
阅读数 4.1K

本文是《轻量级 Java Web 框架架构设计》的系列博文。

最近有些朋友一直在问我关于 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 应用程序的利器!

由于 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 返回,因为它是由框架进行管理的。

对于以上三种方案,均有利弊,还请广大网友提供进行评判,或给出更好的方案。期待您的反馈!

展开阅读全文
加载中
点击加入讨论🔥(8) 发布并加入讨论🔥
打赏
8 评论
26 收藏
2
分享
返回顶部
顶部