简单实现的Model 2架构

在Servlet程序中夹杂HTML的画面输出绝对不是什么好主意,即冗余又麻烦又难看,尽管JSP代码相比Servlet优化了许多,但在JSP网页中的HTML间夹杂Java程序代码,仍然看起来很凌乱,后期的修改维护也很麻烦。

谈及Web应用程序架构上的设计时,总会谈到MVC和model 2这两个名词。MVC是Model、View、Controller的缩写,大家再熟悉不过。这里译为模型、视图、控制器,分别代表应用程序中三种职责各不相同的对象。最原始的MVC模式其实是指桌面应用程序的一种设计方式,为了让同一份数据能有不同的画面呈现方式,并且当数据被变更时,画面可获得通知并根据资料更新画面呈现。

MVC 互动示意图

可以看出,MVC模型是个职责分明的设计方式:

  1. 模型不会有画面相关的程序代码
  2. 视图负责画面相关逻辑
  3. 控制器知道某个操作必须调用那些模型

后来有人认为,MVC这样的职责分配,可以套用在WEB应用程序的设计上:

  1. 视图部分可由网页来实现
  2. 服务器上的数据访问或业务逻辑(Business logic)由模型负责
  3. 控制器接送浏览器的请求,决定调用哪些模型来处理

然而,桌面应用程序上的MVC设计方式,有个与Web应用程序决定性的不同。Web应用程序是基于HTTP,必须基于请求/响应模型,没有请求就不会有响应,也就是HTTP服务器不可能主动对浏览器发出响应。因此,对MVC的行为作了变化,因而形成所谓的Model 2架构。

基于请求&响应修正MVC而产生的Model 2架构

在Model 2的架构上,仍将程序职责分为模型(Model)、视图(View)、控制器(Controller),因此该架构也称为MVC,或并称为MVC/model 2。

在Model 2的架构上,控制器、模型、视图各负的职责:

  • 控制器:取得请求参数、验证请求参数、转发请求给模型、转发请求给画面,这些都使程序代码来实现。
  • 模型:接受控制器的请求调用,负责处理业务逻辑、负责数据存取逻辑等,这部分还可依应用程序功能,产生各多种不同职责的模型对象,模型使用程序代码来实现。
  • 视图:接受控制器的请求调用,会从模型提取运算后的结果,根据需求呈现所需的画面,在职责分配良好的情况下,基本上可做到不出现程序代码,因此不会发生程序代码与HTML混杂在一起的情况。

既然了解了MVC/model 2模型的基本原理,下面简单实现以下:

HelloController.java (控制器,负责参数的请求与转发)

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Barudisshu
 */
@WebServlet(name = "HelloController", urlPatterns = {"/hello.do"})
public class HelloController extends HttpServlet {

    private HelloModel model = new HelloModel();

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //收集请求参数
        String name = request.getParameter("user");
        //委托HelloModel对象处理
        String message = model.doHello(name);
        //将结果信息设置到请求对象成为属性
        request.setAttribute("message", message);
        //转发hello.view进行相应
        request.getRequestDispatcher("equivalent.jsp").forward(request, response);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

HelloModel.java (模型,负责处理业务逻辑、数据存取逻辑等)

import java.util.HashMap;
import java.util.Map;

/**
 *
 * @author Barudisshu
 */
class HelloModel {

    private Map<String, String> messages = new HashMap<>();

    public HelloModel() {
        messages.put("caterpillar", "Hello");
        messages.put("Justin", "Welcome");
        messages.put("momor", "Hi");
    }

    public String doHello(String user) {
        String message = messages.get(user);
        return message + "," + user + "!";
    }
}

HelloView.java (视图,用于呈现结果,基本上做到不出现程序代码)

/**
 *
 * @author Barudisshu
 */
@WebServlet(name = "HelloView", urlPatterns = {"/hello.view"})
public class HelloView extends HttpServlet {

    private String htmlTemplate =
            "<!doctype html>"
            + "<html>"
            + "<head>"
            + "<meta charset='utf-8'>"
            + "<title>%s</title>"
            + "</head>"
            + "<body>"
            + "<h1>%s</h1>"
            + "</body>"
            + "</html>";

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //取得请求参数
        String user = request.getParameter("user");
        //取得请求属性
        String message = (String) request.getAttribute("message");
        //产生html结果
        String html = String.format(htmlTemplate, user, message);
        response.getWriter().print(html);
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

equivalent.jsp (视图,等效于HelloView,使用EL表达语言,没有出现任何Java代码)

<%-- 
    Document   : equivalent
    Created on : 2013-8-26, 19:58:04
    Author     : Barudisshu
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>${param.user}</title>
    </head>
    <body>
        <h1>${message}</h1>
    </body>
</html>

可以看到,在Model 2架构的实现下,控制器、视图、模型各司其职,该呈现画面的元件不会有Java代码出现(HelloView),在负责业务逻辑的元件不会有HTML输出(HelloModel),该处理请求参数的元件不会牵涉业务逻辑的代码(HelloController)。

转载于:https://my.oschina.net/Barudisshu/blog/157062

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值