全栈工程师修炼指南

解耦是永恒的主题:MVC框架的发展

2020-11-09  本文已影响0人  码农架构

JSP 和 Servlet

概念介绍

Servlet 指的是服务端的一种 Java 写的组件,它可以接收和处理来自浏览器的请求,并生成结果数据,通常它会是 HTML、JSON 等常见格式,写入 HTTP 响应,返回给用户。

JSP,它的全称叫做 Java Server Pages,它允许静态的 HTML 页面插入一些类似于“<% %>”这样的标记(scriptlet),而在这样的标记中,还能以表达式或代码片段的方式,嵌入一些 Java 代码,在 Web 容器响应 HTTP 请求时,这些标记里的 Java 代码会得到执行,这些标记也会被替换成代码实际执行的结果,嵌入页面中一并返回。这样一来,原本静态的页面,就能动态执行代码,并将执行结果写入页面了。

动手验证

现在你可以打开 hello_005fworld_jsp.java,如果你有 Java 基础,那么你应该可以看得懂其中的代码。代码中公有类 hello_005fworld_jsp 继承自 HttpJspBase 类,而如果你查看 Tomcat 的 API 文档,你就会知道,原来它进一步继承自 HttpServlet 类,也就是说,这个自动生成的 Java 文件,就是 Servlet

out.write("Hello world! Time: ");
out.print( new java.util.Date() );
out.write('\n');

JSP 和 Servlet 并不是完全独立的“两个人”,JSP 实际工作的时候,是以 Servlet 的形式存在的,也就是说,前者其实是可以转化成后者的。

深入理解

为什么不直接使用 Servlet,而要设计出 JSP 这样的技术,让其在实际运行中转化成 Servlet 来执行呢?

命令式代码,在 Servlet 中,它会一条一条语句告诉计算机下一步该做什么,这个过程就是命令式的。我们绝大多数的代码都是命令式的。声明式代码是告诉计算机“什么样”,而不关注“怎么做”;命令式代码则是告诉计算机“怎么做”,而不关注“什么样”。

为什么需要两种方式?

计算机生来就是遵循命令执行的,因此声明式的 JSP 页面会被转化成一行行命令式的 Servlet 代码,交给计算机执行。可是,你可以想象一下,如果 HTML 那样适合声明式表述的代码,程序员使用命令式来手写会是怎样的一场噩梦——代码将会变成无趣且易错的一行行字符串拼接。

MVC 的演进

MVC 模式包含这样三层:

JSP Model 1

JSP Model 1 是整个演化过程中最古老的一种,请求处理的整个过程,包括参数验证、数据访问、业务处理,到页面渲染(或者响应构造),全部都放在 JSP 页面里面完成。JSP 页面既当爹又当妈,静态页面和嵌入动态表达式的特性,使得它可以很好地容纳声明式代码;而 JSP 的 scriptlet,又完全支持多行 Java 代码的写入,因此它又可以很好地容纳命令式代码。

image.png

JSP Model 2

在 Model 1 中,你可以对 JSP 页面上的内容进行模块和职责的划分,但是由于它们都在一个页面上,物理层面上可以说是完全耦合在一起,因此模块化和单一职责无从谈起。和 Model 1 相比,Model 2 做了明显的改进。

image.png

MVC 的一般化

JSP Model 2 已经具备了 MVC 的基本形态,但是,它却对技术栈有着明确限制——Servlet、JSP 和 JavaBean。今天我们见到的 MVC,已经和实现技术无关了,并且,在 MVC 三层大体职责确定的基础上,其中的交互数据流动却是有许多不同的实现方式的。

第一种

image.png

用户请求发送给 Controller,而 Controller 是大总管,需要主动调用 Model 层的接口去取得实际需要的数据对象,之后将数据对象发送给需要渲染的 View,View 渲染之后返回页面给用户。

在这种情况下,Controller 往往会比较大,因为它要知道需要调用哪个 Model 的接口获取数据对象,还需要知道要把数据对象发送给哪个 View 去渲染;View 和 Model 都比较简单纯粹,它们都只需要被动地根据 Controller 的要求完成它们自己的任务就好了。

第二种

image.png

Controller 调用 Model 的接口发起数据更新操作,接着就直接转向最终的 View 去了;View 会调用 Model 去取得经过 Controller 更新操作以后的最新对象,渲染并返回给用户。

Controller 先调用 Model, 再调用 View, 而 View 调用 Model.

在这种情况下,Controller 相对就会比较简单,而这里写操作是由 Controller 发起的,读操作是由 View 发起的,二者的业务对象模型可以不相同,非常适合需要 CQRS(Command Query Responsibility Segregation,命令查询职责分离)的场景

MVC 的变体

当它的核心三层和它们的基本职责发生变化,这样的架构模式就不再是严格意义上的 MVC 了。这里我介绍两种 MVC 的变体:MVP 和 MVVM。

MVP

MVP 包含的三层为 Model、View 和 Presenter,它往往被用在用户的界面设计当中,和 MVC 比起来,Controller 被 Presenter 替代了。

Presenter: 主持人.

image.png

MVVM

MVVM 是在 MVP 的基础上,将职责最多的 Presenter 替换成了 ViewModel,它实际是一个数据对象的转换器,将从 Model 中取得的数据简化,转换为 View 可以识别的形式返回给 View。View 和 ViewModel 实行双向绑定,成为命运共同体,即 View 的变化会自动反馈到 ViewModel 中,反之亦然。

image.png 公众号:码农架构
上一篇 下一篇

猜你喜欢

热点阅读