文档章节

用 Hasor 谈一谈MVC设计模式

哈库纳
 哈库纳
发布于 2016/09/29 08:51
字数 1292
阅读 184
收藏 1

    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模式。

© 著作权归作者所有

哈库纳

哈库纳

粉丝 964
博文 84
码字总数 152107
作品 4
杭州
架构师
私信 提问
Java 设计模式(14) —— 复合模式

一、复合模式 模式常一起使用,组合在一个设计解决方案中 复合模式在一个解决方案中结合两个或多个模式,能解决一般性或一系列的问题 二、示例 本次设计模式讲解中无代码示例,由于复合模式是...

磊_lei
2018/05/26
0
0
JavaScript 设计模式解析【2】——结构型设计模式

前情提要: JavaScript 设计模式解析【1】——创建型设计模式 适配器模式 适配器模式主要用来解决两个已有接口之间不匹配的问题,它不考虑这些接口是怎么实现的,也不考虑他们将来会如何演化。...

Reaper622
2019/10/03
0
0
android与模式:设计原则

在谈设计模式之前,如果不谈设计原则,我认为是无根之浮萍。 为什么这么说,为什么我们要学设计模式,为什么前人将这些东西抽象和总结出来?这就是要了解设计原则的必要性,开始学的时候,可...

今幕明
2014/03/06
97
0
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
2018/06/24
0
0
设计模式(Swift) - 3.观察者模式、建造者模式

上一篇 设计模式(Swift) - 2.单例模式、备忘录模式和策略模式中讲了三种常见的设计模式. 单例模式: 限制了类的实例化,一个类只能实例化一个对象,所有对单例对象的引用都是指向了同一个对象....

Dariel
2018/07/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

2020,向死而生

或许2020年注定是非常艰难的一年,毕竟两个轮回前之的1900年,清廷过得也很艰难,义和团在北方闹得轰轰烈烈,紫禁城也被八国联军占领。次年(1901年)即签订了后世所谓的丧权辱国的辛丑条约,...

嘉树
11分钟前
0
0
git 常用配置

git config --global core.compression 0 git config --global http.lowSpeedLimit 0 git config --global http.lowSpeedTime 999999 git config --global http.postBuffer 524288000......

老码农008
11分钟前
2
0
Protel99SE WIN10系统下无法添加封装库的解决方法

Protel99SE WIN10系统下无法添加封装库的解决方法 Protel99SE这款PCB设计软件实在太古老了,导致与微软的最新操作系统有些功能不能兼容,比如WIN10系统下无法添加封装库;但是由于Protel99S...

demyar
13分钟前
1
0
大数据风控系统概述

为什么要做风控系统 不做的话,会有以下风险: 各种小号、垃圾账号泛滥 撞库攻击、盗号、毁号、拖库等 拉新 10w 留存率不到 5% 百万营销费用,却增加不了用户粘性 投票票数差距非常悬殊 各种...

大数据技术进阶
13分钟前
3
0
串口调试助手,VB6.0开发

1、为什么要自己开发一个串口调试助手 通常我们都是:在网上直接下载一个串口助手,可执行文件,直接使用,并无法得到其源码,在此我们提供了一个VB6.0开发的串口助手: (1)让你极速掌握串...

superman150
16分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部