用 Hasor 谈一谈MVC设计模式

随声附和 提交于 2019-11-30 05:05:40

    MVC 是一个老生常谈的东西早已不是什么稀罕物件,不过在这里还是扒一扒到底都有多少种 MVC。

一、经典 MVC

    先说最经典的 MVC,一个请求控制器的请求,负责读取数据,然后将数据派发到试图上。如图:

    在经典 MVC 中,可以看到我们请求的页面并不是真正的页面,而是一个控制器。具体显示的页面由这个控制器来决定,大名顶顶的 struts 框架就是这样一种模式。然而,通常为了记忆方便,基于这种经典模式的 MVC 我们通常是把 Controller 的名字起的和 View 一样。

    这种模式下,Controller 的职责主要有两个:1、确定显示的最终页面。2、执行页面逻辑准备相关数据。

    在 View 中使用的数据是来自 Controller 给予的。

    例如“判断当前用户是否登录,如果登录则展现用户详细信息,如果未登录则展现登录界面”。这种场景比较适合这种模式。

 

二、视图前置 MVC

    这是 MVC 的一个变版,在这种模式中 View 的地位被提升到 Controller 之前。也就是说请求是先得到了要显示的页面,而页面中的数据的获取逻辑被后置的 Controller 提供。

    这种模式下,Controller 的职责变得只有一个,那就是:执行页面逻辑准备相关数据。视图前置这种模式在职责上更加清晰,但是它失去了对页面展现的控制。

    通常在某个数据集中展现的地方会有这种模式的身影,例如:List 页面,在List 页面通常伴随着查询、分页。这种页面中页面本身一般是不会有太大的变化,更多的是后台的数据提取逻辑。

    其实这种 MVC 我们也并不陌生,jsp + bean 就是这样一种形式。

 

三、视图前置 MVC 变版

    这是 视图前置 MVC 的一个变版,它的工作模式没有太大的变化。不同的是 View 被进一步前置到 浏览器中,通过 javascript 通过 ajax 的方式访问 Controller。

    这种模式下,一般有两类工程师共同开发一个应用程序,他们是:前段工程师、后段工程师。

    这种模式的优点在于,前后端开发工程师,只需要协议数据交换格式。即可开始各自的开发工作。也是最常见的一种模式。这也是前后端分离的一种体现。

 

四、使用 Hasor 实现三种 MVC 模式的开发

-Controller

    我们先以 Controller 为例子进行说明,下面是使用 Hasor 开发的 Controller。

@MappingTo("/index.htm")
public class Index {
    public void execute(RenderData data) {
        data.put("data", new UserData());
    }
}

    在例子中,我们简单的把 UserData 这个数据写入到 RenderData 对象中。最后在页面渲染的时候再把这个对象拿出来。

    当然您也可以像这样,直接把对象塞到 Request 中。

data.getHttpRequest().setAttribute("data", new UserData());

    或者干脆更直接一点

@MappingTo("/index.htm")
public class Index {
    public void execute(HttpServletRequest request) {
        request.setAttribute("data", new UserData());
    }
}

    除了前面三种方式之外,Haosr 还学习优秀的 JFinal 框架。您可以继承一个类,通过继承类的各种工具方法来实现数据的设置,例如:

@MappingTo("/index.htm")
public class Index extends WebController {
    public void execute() {
        this.putData("data", new UserData());
        // or
        this.setAttr("data", new UserData());
    }
}

    具体想用哪种方式,你喜欢就好。

-实践:经典MVC设计模式

    我们可以通过这种方式实现 经典MVC模式。如下:

@MappingTo("/index.htm")
public class Index extends WebController {
    public void execute() throws ServletException, IOException {
        // 方式 1
        this.setAttr("data", new UserData());
        getRequest().getRequestDispatcher("/userinfo.htm").forward(getRequest(),getResponse());

        // 方式 2
        this.setAttr("data", new UserData());
        getResponse().sendRedirect("/userinfo.htm");

        // 方式 3
        this.setAttr("data", new UserData());
        renderTo("/userInfo.htm");
    }
}

你也可以这样:

@MappingTo("/index.htm")
public class Index {
    public void execute(RenderData data) {
        data.put("data", new UserData());
        data.viewName("/userInfo.htm");
    }
}

-实践:视图前置 MVC

    前面提到过,前置 mvc 就是一种 jsp + bean 的模式。那么索性就 “JSP + Bean”把。先看负责获取数据的 ManagerBean,为了减少每次获取 UserInfo 时重复创建 Manager 的问题。下面还特意添加了@Singleton注解实现了单例。

@Singleton
public class UserManager {
    public UserInfo getUserById(long userId) {
        return new UserInfo();
    }
}

    接下来真的 JSP 登场,为了JSP可以访问到我们的 Bean,你需要引入 Hasor 的 JSP 标签库。接下来通过 hs 库访问我们的 ManagerBean 获取 UserInfo。

<%@page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ taglib prefix="hs" uri="http://project.hasor.net/hasor/schema/jstl" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="zh-CN">
<body>

<hs:findType var="userManager" type="net.demo.hasor.manager.UserManager"/>
<c:set var="userInfo" scope="request" value="${userManager.getUserById(1234)}"/>
姓名:${userInfo.name}<br/>
年龄:${userInfo.age}<br/>

</body>
</html>

    下面这个是运行结果:

-实践:视图前置 MVC 变版

    在这种模式下我们需要借助一个 Controller 帮我们把数据透给前端 js 程序。浏览器通过请求我们的接口 Controller 来获取数据。接口 Controller 负责返回 json 数据。

@MappingTo("/getUserInfo.json")
public class GetUserInfo {
    public UserInfo execute(RenderData data) {
        return new UserInfo();
    }
}

    访问URL运行结果:

    其实这种模式,本质上还是经典MVC模式。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!