模型 - 视图 - 控制器( MVC )是 80 年代 Smalltalk-80 出现的一种软件设计模式,现在已经被广泛的使用。
1
、模型(
Model
)
模型是应用程序的主体部分。模型表示业务数据,或者业务逻辑
.
2
、视图(
View
)
视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面。
3
、控制器(
controller)
控制器工作就是根据用户的输入,控制用户界面数据显示和更新
model
对象状态。
MVC
式的出现不仅实现了功能模块和显示模块的分离,同时它还提高了应用系统的可维护性、可扩展性、可移植性和组件的可复用性
早期的程序中,如果不注意对数功能和显示的解耦合,常常会导致程序的复杂及难以维护。很多
VB,Delphi
等
RAD
程序都有这种问题。甚至现在的
C#,Java
有时候也会出现把业务逻辑写在显示模块中的现象
管
MVC
设计模式很早就提出,但在
Web
项目的开发中引入
MVC
却是步履维艰。主要原因:一是在早期的
Web
项目的开发中,程序语言和
HTML
的分离一直难以实现。
CGI
程序以字符串输出的形式动态地生成
HTML
内容。后来随着脚本语言的出现,前面的方式又被倒了过来,改成将脚本语言书写的程序嵌入在
HTML
内容中。这两种方式有一个相同的不足之处即它们总是无法将程序语言和
HTML
分离。二是脚本语言的功能相对较弱,缺乏支持
MVC
设计模式的一些必要的技术基础。
mode1 1 是一个以 JSP 文件为中心的模式,在这种模式中 JSP 页面不仅负责表现逻辑,也负责控制逻辑。专业书籍上称之为逻辑耦合在页面中,这种处理方式,对一些规模很小的项目如:一个简单的留言簿,也没什么太大的坏处,实际上,人们开始接触一些对自己来说是新的东西的时候,比如,用 JSP 访问数据库时,往往喜欢别人能提供一个包含这一切的单个 JSP 页面,因为这样在一个页面上他就可以把握全局,便于理解。但是,用 Model 1 模式开发大型时,程序流向由一些互相能够感知的页面决定,当页面很多时要清楚地把握其流向将是很复杂的事情,当您修改一页时可能会影响相关的很多页面,大有牵一发而动全身的感觉,使得程序的修改与维护变得异常困难;还有一个问题就是程序逻辑开发与页面设计纠缠在一起,既不便于分工合作也不利于代码的重用,这样的程序其健壮性和可伸缩性都不好。 Grady Booch 等人在 UML 用户指南一书中,强调建模的重要性时,打了一个制作狗窝、私人住宅、和大厦的形象比喻来说明人们处理不同规模的事物时应该采用的合理方法一样,人们对不同规模的应用程序也应该采用不同的模式
为了克服 Model 1 的缺陷,人们引入了 Model 2
它引入了 \" 控制器 \" 这个概念,控制器一般由 servlet 来担任,客户端的请求不再直接送给一个处理业务逻辑的 JSP 页面,而是送给这个控制器,再由控制器根据具体的请求调用不同的事务逻辑,并将处理结果返回到合适的页面。因此,这个 servlet 控制器为应用程序提供了一个进行前 - 后端处理的中枢。一方面为输入数据的验证、身份认证、日志及实现国际化编程提供了一个合适的切入点;另一方面也提供了将业务逻辑从 JSP 文件剥离的可能。业务逻辑从 JSP 页面分离后, JSP 文件蜕变成一个单纯完成显示任务的东西,这就是常说的 View 。而独立出来的事务逻辑变成人们常说的 Model, 再加上控制器 Control 本身,就构成了 MVC 模式。实践证明, MVC 模式为大型程序的开发及维护提供了巨大的便利。
其实, MVC 开始并不是为 Web 应用程序提出的模式,传统的 MVC 要求 M 将其状态变化通报给 V ,但由于 Web 浏览器工作在典型的拉模式而非推模式,很难做到这一点。因此有些人又将用于 Web 应用的 MVC 称之为 MVC2 。正如上面所提到的 MVC 是一种模式,当然可以有各种不同的具体实现,包括您自己就可以实现一个体现 MVC 思想的程序框架, Struts 就是一种具体实现 MVC2 的程序框架。它的大致结构如图三所示
图基本勾勒出了一个基于
Struts
的应用程序的结构,从左到右,分别是其表示层(
view
)、控制层
(controller)
、和模型层
(Model)
。其表示层使用
Struts
标签库构建。来自客户的所有需要通过框架的请求统一由叫
ActionServlet
的
servlet
接收(
ActionServlet Struts
已经为我们写好了,只要您应用没有什么特别的要求,它基本上都能满足您的要求),根据接收的请求参数和
Struts
配置
(struts-config.xml)
中
ActionMapping
,将请求送给合适的
Action
去处理,解决由谁做的问题,它们共同构成
Struts
的控制器。
Action
则是
Struts
应用中真正干活的组件,开发人员一般都要在这里耗费大量的时间,它解决的是做什么的问题,它通过调用需要的业务组件(模型)来完成应用的业务,业务组件解决的是如何做的问题,并将执行的结果返回一个代表所需的描绘响应的
JSP
(或
Action
)的
ActionForward
对象给
ActionServlet
以将响应呈现给客户。
过程如图所示:
这里要特别说明一下的是:就是 Action 这个类,上面已经说到了它是 Struts 中真正干活的地方,也是值得我们高度关注的地方。 将业务对象从 Action 分离出来后有利于它的重用,同时也增强了应用程序的健壮性和设计的灵活性。因此,它实际上可以看作是 Controller 与 Model 的适配器,如果硬要把它归于那一部分,笔者更倾向于后一种看法,即它是 Controller 的一部分,换句话说,它不应该包含过多的业务逻辑,而应该只是简单地收集业务方法所需要的数据并传递给业务对象。
上面这样简单的描述,初学者可能会感到有些难以接受,下面举个比较具体的例子来进一步帮助我们理解。如:假设,我们做的是个电子商务程序,现在程序要完成的操作任务是提交定单并返回定单号给客户,这就是关于做什么的问题,应该由 Action 类完成,但具体怎么获得数据库连接,插入定单数据到数据库表中,又怎么从数据库表中取得这个定单号(一般是自增数据列的数据),这一系列复杂的问题,这都是解决怎么做的问题,则应该由一个(假设名为 orderBo )业务对象即 Model 来完成。 orderBo 可能用一个返回整型值的名为 submitOrder 的方法来做这件事, Action 则是先校验定单数据是否正确,以免常说的垃圾进垃圾出;如果正确则简单地调用 orderBo 的 submitOrder 方法来得到定单号;它还要处理在调用过程中可能出现任何错误;最后根据不同的情况返回不同的结果给客户。