三层架构和mvc资料整合.docx
《三层架构和mvc资料整合.docx》由会员分享,可在线阅读,更多相关《三层架构和mvc资料整合.docx(17页珍藏版)》请在冰豆网上搜索。
![三层架构和mvc资料整合.docx](https://file1.bdocx.com/fileroot1/2023-1/4/7d5dc333-5d79-4bb0-8a57-9d500455b27e/7d5dc333-5d79-4bb0-8a57-9d500455b27e1.gif)
三层架构和mvc资料整合
WEB三层架构与MVC
而我发此文的目的有二:
一者,让初学者能够听到一家之言,是为解惑;二者,更希望抛砖引玉,得到专家的批判。
许多学生经常问我,MVC到底和WEB三层架构有啥关系?
开始时,我也只能给他们一些模糊的回答。
时间长了,自己的良心开始受到谴责。
对于一个程序员来说,这个问题显得挺学究。
我在跟自己的许多程序员朋友以及同行(Java讲师)都对MVC和WEB三层架构的关系做了探讨。
现在可以说对WEB三层架构和MVC之间的关系理出了头绪。
此可谓教学相长。
先说说Web三层架构这个古老话题。
地球人都知道web三层架构是指:
∙>用户接口层(UILayer)
∙>业务逻辑层(BussinessLayer)
∙>持久化层
关于业务逻辑和用户接口
在早期的web开发中,因为业务比较简单,并没有这三层的划分。
用户数据的呈现及输入的接收、封装、验证、处理、以及对数据库的操作,都放在jsp页面中。
这时的开发,好比盘古尚未开天辟地,整个web开发就是一片“混沌”。
随着业务越来越复杂,人们开始考虑更好的利用OOP这把利刃来解决问题。
于是有人发现把业务逻辑抽取出来并形成与显示和持久化无关的一层,能够让业务逻辑清晰,产品更便于维护。
这就是SUN当初倡导的JSPModel1开发方式。
关于持久化
JSPM1开发方式中,并没有对数据如何持久化给出建议。
在许多公司中,它们的产品是以数据库为中心进行架构和设计的。
在他们的产品里,虽然也有DAO层,但是职责不清。
为什么这么说呢,因为我发现在许多人眼里,DAO层的指责很简单——增删改查。
但我认为,这样理解实际上是本末倒置了。
对于简单数据的管理来说,这样理解无可厚非。
但随着业务逻辑变得日益复杂。
我们实在是被复杂的对象关系搞头疼了,如果这时我们还要考虑如何把数据存储起来(通常的情况下是存到关系型数据库中),我们开始抱怨自己软件的架构太恶心,一团糟。
面向对象设计思想教会我们——如果我们不想做这件事,就交给别人做吧!
这时聪明的架构师们提出了一个概念——持久化。
如果我们在自己的应用中添加一个新的层——专门负责对象状态的持久化保存及同步,那不就可以全心全意的“搞对象”了吗?
持久化概念的产生,代表着我们对关系型数据库的依赖降低了。
因此甚至有人推断——数据库已死。
同时,关系型数据库这个新的概念也不断形成,并演化成理论,又由理论衍生出产品。
因此一个意识良好的程序员,至少应该认同,持久化并不是产品中最重要的环节——最重要的环节是清晰正确的业务逻辑。
灰色地带
是的,从理论上看,web三层架构很美了。
但在实际开发产品的时候,我们发现了很多问题。
主要问题就是用UI层和业务层之间有许多灰色地带。
这些灰色地带业务逻辑层不想管,UI层也不想管。
让我们举一些例子:
例子1,难以管理的页面跳转关系
上图是我在讲JSP课程时,一个简单案例的页面跳转关系图。
这是一个十分简单的例子,但页面跳转关系已经挺复杂了。
试想,如果你正在做一个有上百张表,十几个核心模块,几百个页面的产品时,这张图将变得多么复杂!
而问题是,这些页面跳转关系分散在JSP和Servlet中,非常难以管理。
例子2,表单数据的验证及封装:
假设我们正在做一个简单的表单提交,我们希望对用户数据的数据进行验证和封装,最终交给业务逻辑层一个实体对象。
从三层架构分析,我们想要做的事情是这样的:
但是该把验证和封装数据的工作交给谁来做呢?
UI层还是业务逻辑层?
都不太合适!
例子3,国际化:
如果我们想为不同国家和地区的人提供不同的语言,无疑需要国际化的支持。
那么,我们需要在JSP页面上根据用户的配置或请求信息判断应该为该用户呈现哪国文字。
而这些判断和显示的逻辑应该划分到业务逻辑层还是UI层呢?
用MVC的思路解决问题
对于纠缠不清的问题,我们总要想办法将其分解。
MVC是一种设计思想。
这种思想强调实现模型(Model)、视图(View)和控制器的分离。
这种思想是如何作用于web的呢?
实际上,我们在web开发中引入MVC思想,想要达到的目的是:
实现UI层和业务逻辑层分离——控制器是为了实现上述目的而存在的!
在解决了持久化的问题后,我们发现,我们的所说的业务逻辑层和MVC中的Model指的是一回事,我们所说的UI层和MVC中的View是一回事。
MVC提供了让模型和视图相分离的思路——引入控制器。
我们把页面跳转关系管理、表单数据的封装及验证、国际化等任务交给控制器处理。
因此,也不难理解为什么流行的MVC框架都具有管理页面跳转关系、表单数据的封装及验证、国际化等特性。
总结
在Javaweb开发中,MVC框架充当了UI层和业务逻辑层的适配器的作用。
MVC框架实现了UI层和业务逻辑层最大程度的分离。
使用mvc的好处,MVC使用规则,java三层架构设计思想
java开发web应用
MVC使用规则
为了提供可重用的设计及代码,M-V-C之间的交互应该很好地定义,以及它们相互间地依赖关系要尽量最小。
使用MVC模式的其中一个目的就是,使一个单一的模型能与多个视图及控制器联合起来。
MVC模型保证了视图能与模型同步。
当控制器从用户输入中接受到一个有效的命令后,它将调用模型上的相应方法。
模型将确认该操作是否与当前的状态一致,然后再执行它,并相应地修改视图的状态。
而视图,作为一个观察者,将根据得到的模型状态改变来更新它的显示。
依赖关系保持最小
为了使一个模型能在多个视图及控制器中使用,它们之间的依赖关系必须保持最小。
要做到这些,必须遵守一下规则(如图10-03):
注意:
A依赖于B,表示A的代码中需要与B相关的信息,如调用B的方法或使用B的属性。
1、 模型必须与视图及控制器没有任何依赖关系。
2、 视图依赖于与它相关的模型,它必须知道模型状态结构,这样才能把模型显示出来。
3、 视图不能依赖与控制器,这样的话,几个不同的控制器可以关联相同视图。
4、 控制器依赖于相关的模型及视图,模型定义了控制器能调用的方法,而视图定义上下关系,通过它控制器可以解释用户输入信息。
这使得控制器能紧紧地跟视图联系在一起。
图10-03MVC模式中允许的依赖关系
交互必须保持最小
另外一个需要使用多视图及多控制器的前提条件就是保存最小的交互。
特别是,控制器一定不要直接影响与它相关联的视图的显示。
而是在用户输入产生的影响在视图中可见之前,控制器必须与模型进行一个完整的往返交互,这样能保证一个状态修改能更新所有的视图,以及视图能保持与模型同步。
使用单一控制器的实现通常会违反这种规则,因为一些不够严谨的思维:
“我已经知道这个状态修改要发生,所以不需要模型来告诉我这个”。
但这是错的,原因有三个:
1、 模型可能因为某些原因否决该操作,然后这个操作就不会发生了。
2、 其他控制器可能同时调用了该模型的操作,有些操作可能也会影响视图的显示,或者使操作不合法。
3、 另外,将来使用其他控制器来扩展这个实现也是可能的。
MVC模式是"Model-View-Controller"的缩写,中文翻译为"模式-视图-控制器"。
MVC应用程序总是由这三个部分组成。
Event(事件)导致Controller改变Model或View,或者同时改变两者。
只要Controller改变了Models的数据或者属性,所有依赖的View都会自动更新。
类似的,只要Controller改变了View,View会从潜在的Model中获取数据来刷新自己。
MVC模式最早是smalltalk语言研究团提出的,应用于用户交互应用程序中。
smalltalk语言和java语言有很多相似性,都是面向对象语言,很自然的SUN在petstore(宠物店)事例应用程序中就推荐MVC模式作为开发Web应用的架构模式。
MVC模式是一种架构模式,其实需要其他模式协作完成。
在J2EE模式目录中,通常采用servicetoworker模式实现,而servicetoworker模式可由集中控制器模式,派遣器模式和PageHelper模式组成。
而Struts只实现了MVC的View和Controller两个部分,Model部分需要开发者自己来实现,Struts提供了抽象类Action使开发者能将Model应用于Struts框架中。
MVC模式是一个复杂的架构模式,其实现也显得非常复杂。
但是,我们已经终结出了很多可靠的设计模式,多种设计模式结合在一起,使MVC模式的实现变得相对简单易行。
Views可以看作一棵树,显然可以用CompositePattern来实现。
Views和Models之间的关系可以用ObserverPattern体现。
Controller控制Views的显示,可以用StrategyPattern实现。
Model通常是一个调停者,可采用MediatorPattern来实现。
现在让我们来了解一下MVC三个部分在J2EE架构中处于什么位置,这样有助于我们理解MVC模式的实现。
MVC与J2EE架构的对应关系是:
View处于WebTier或者说是ClientTier,通常是JSP/Servlet,即页面显示部分。
Controller也处于WebTier,通常用Servlet来实现,即页面显示的逻辑部分实现。
Model处于MiddleTier,通常用服务端的javaBean或者EJB实现,即业务逻辑部分的实现。
一、MVC设计思想
MVC英文即Model-View-Controller,即把一个应用的输入、处理、输出流程按照Model、View、Controller的方式进行分离,这样一个应用被分成三个层——模型层、视图层、控制层。
视图(View)代表用户交互界面,对于Web应用来说,可以概括为HTML界面,但有可能为XHTML、XML和Applet。
随着应用的复杂性和规模性,界面的处理也变得具有挑战性。
一个应用可能有很多不同的视图,MVC设计模式对于视图的处理仅限于视图上数据的采集和处理,以及用户的请求,而不包括在视图上的业务流程的处理。
业务流程的处理交予模型(Model)处理。
比如一个订单的视图只接受来自模型的数据并显示给用户,以及将用户界面的输入数据和请求传递给控制和模型。
模型(Model):
就是业务流程/状态的处理以及业务规则的制定。
业务流程的处理过程对其它层来说是黑箱操作,模型接受视图请求的数据,并返回最终的处理结果。
业务模型的设计可以说是MVC最主要的核心。
目前流行的EJB模型就是一个典型的应用例子,它从应用技术实现的角度对模型做了进一步的划分,以便充分利用现有的组件,但它不能作为应用设计模型的框架。
它仅仅告诉你按这种模型设计就可以利用某些技术组件,从而减少了技术上的困难。
对一个开发者来说,就可以专注于业务模型的设计。
MVC设计模式告诉我们,把应用的模型按一定的规则抽取出来,抽取的层次很重要,这也是判断开发人员是否优秀的设计依据。
抽象与具体不能隔得太远,也不能太近。
MVC并没有提供模型的设计方法,而只告诉你应该组织管理这些模型,以便于模型的重构和提高重用性。
我们可以用对象编程来做比喻,MVC定义了一个顶级类,告诉它的子类你只能做这些,但没法限制你能做这些。
这点对编程的开发人员非常重要。
业务模型还有一个很重要的模型那就是数据模型。
数据模型主要指实体对象的数据保存(持续化)。
比如将一张订单保存到数据库,从数据库获取订单。
我们可以将这个模型单独列出,所有有关数据库的操作只限制在该模型中。
控制(Controller)可以理解为从用户接收请求,将模型与视图匹配在一起,共同完成用户的请求。
划分控制层的作用也很明显,它清楚地告诉你,它就是一个分发器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。
控制层并不做任何的数据处理。
例如,用户点击一个连接,控制层接受请求后,并不处理业务信息,它只把用户的信息传递给模型,告诉模型做什么,选择符合要求的视图返回给用户。
因此,一个模型可能对应多个视图,一个视图可能对应多个模型。
模型、视图与控制器的分离,使得一个模型可以具有多个显示视图。
如果用户通过某个视图的控制器改变了模型的数据,所有其它依赖于这些数据的视图都应反映到这些变化。
因此,无论何时发生了何种数据变化,控制器都会将变化通知所有的视图,导致显示的更新。
这实际上是一种模型的变化-传播机制。
模型、视图、控制器三者之间的关系和各自的主要功能,如图1所示。
二、MVC设计模式的实现
ASP.NET提供了一个很好的实现这种经典设计模式的类似环境。
开发者通过在ASPX页面中开发用户接口来实现视图;控制器的功能在逻辑功能代码(.cs)中实现;模型通常对应应用系统的业务部分。
在ASP.NET中实现这种设计而提供的一个多层系统,较经典的ASP结构实现的系统来说有明显的优点。
将用户显示(视图)从动作(控制器)中分离出来,提高了代码的重用性。
将数据(模型)从对其操作的动作(控制器)分离出来可以让你设计一个与后台存储数据无关的系统。
就MVC结构的本质而言,它是一种解决耦合系统问题的方法。
2.1视图
视图是模型的表示,它提供用户交互界面。
使用多个包含单显示页面的用户部件,复杂的Web页面可以展示来自多个数据源的内容,并且网页人员,美工能独自参与这些Web页面的开发和维护。
在ASP.NET下,视图的实现很简单。
可以像开发WINDOWS界面一样直接在集成开发环境下通过拖动控件来完成页面开发本。
本文中介绍每一个页面都采用复合视图的形式即:
一个页面由多个子视图(用户部件)组成;子视图可以是最简单HTML控件、服务器控件或多个控件嵌套构而成的Web自定义控件。
页面都由模板定义,模板定义了页面的布局,用户部件的标签和数目,用户指定一个模板,平台根据这些信息自动创建页面。
针对静态的模板内容,如页面上的站点导航,菜单,友好链接,这些使用缺省的模板内容配置;针对动态的模板内容(主要是业务内容),由于用户的请求不同,只能使用后期绑定,并且针对用户的不同,用户部件的显示内容进行过滤。
使用由用户部件根据模板配置组成的组合页面,它增强了可重用性,并原型化了站点的布局。
视图部分大致处理流程如下:
首先,页面模板定义了页面的布局;页面配置文件定义视图标签的具体内容(用户部件);然后,由页面布局策略类初始化并加载页面;每个用户部件根据它自己的配置进行初始化,加载校验器并设置参数,以及事件的委托等;用户提交后,通过了表示层的校验,用户部件把数据自动提交给业务实体即模型。
这一部分主要定义了WEB页面基类PageBase;页面布局策略类PageLayout,完成页面布局,用于加载用户部件到页面;用户部件基类UserControlBase即用户部件框架,用于动态加载检验部件,以及实现用户部件的个性化。
为了实现WEB应用的灵活性,视图部分也用到了许多配置文件例如:
置文件有模板配置、页面配置、路径配置、验证配置等。
2.2控制器
为了能够控制和协调每个用户跨越多个请求的处理,控制机制应该以集中的方式进行管理。
因此,为了达到集中管理的目的引入了控制器。
应用程序的控制器集中从客户端接收请求(典型情况下是一个运行浏览器的用户),决定执行什么商业逻辑功能,然后将产生下一步用户界面的责任委派给一个适当的视图组件。
用控制器提供一个控制和处理请求的集中入口点,它负责接收、截取并处理用户请求;并将请求委托给分发者类,根据当前状态和业务操作的结果决定向客户呈现的视图。
在这一部分主要定义了HttpReqDispatcher(分发者类)、HttpCapture(请求捕获者类)、Controller(控制器类)等,它们相互配合来完成控制器的功能。
请求捕获者类捕获HTTP请求并转发给控制器类。
控制器类是系统中处理所有请求的最初入口点。
控制器完成一些必要的处理后把请求委托给分发者类;分发者类分发者负责视图的管理和导航,它管理将选择哪个视图提供给用户,并提供给分发资源控制。
在这一部分分别采用了分发者、策略、工厂方法、适配器等设计模式。
为了使请求捕获者类自动捕获用户请求并进行处理,ASP.NET提供低级别的请求/响应API,使开发人员能够使用.NET框架类为传入的HTTP请求提供服务。
为此,必须创作支持System.Web.IHTTPHandler接口和实现ProcessRequest()方法的类即:
请求捕获者类,并在web.config的<httphandlers>节中添加类。
ASP.NET收到的每个传入HTTP请求最终由实现IHTTPHandler的类的特定实例来处理。
IHttpHandlerFactory提供了处理IHttpHandler实例URL请求的实际解析的结构。
HTTP处理程序和工厂在ASP.NET配置中声明为web.config文件的一部分。
ASP.NET定义了一个<httphandlers>配置节,在其中可以添加和移除处理程序和工厂。
子目录继承HttpHandlerFactory和HttpHandler的设置。
HTTP处理程序和工厂是ASP.NET页框架的主体。
工厂将每个请求分配给一个处理程序,后者处理该请求。
例如,在全局machine.config文件中,ASP.NET将所有对ASPx文件的请求映射到HttpCapture类:
<httphandlers>
...
...
</httphandlers>
2.3模型
MVC系统中的模型从概念上可以分为两类――系统的内部状态和改变系统状态的动作。
模型是你所有的商业逻辑代码片段所在。
本文为模型提供了业务实体对象和业务处理对象:
所有的业务处理对象都是从ProcessBase类派生的子类。
业务处理对象封装了具体的处理逻辑,调用业务逻辑模型,并且把响应提交到合适的视图组件以产生响应。
业务实体对象可以通过定义属性描述客户端表单数据。
所有业务实体对象都EntityBase派生子类对象,业务处理对象可以直接对它进行读写,而不再需要和request、response对象进行数据交互。
通过业务实体对象实现了对视图和模型之间交互的支持。
实现时把"做什么"(业务处理)和"如何做"(业务实体)分离。
这样可以实现业务逻辑的重用。
由于各个应用的具体业务是不同的,这里不再列举其具体代码实例。
三、MVC设计模式的扩展
通过在ASP.NET中的MVC模式编写的,具有极其良好的可扩展性。
它可以轻松实现以下功能:
①实现一个模型的多个视图;
②采用多个控制器;
③当模型改变时,所有视图将自动刷新;
④所有的控制器将相互独立工作。
这就是MVC模式的好处,只需在以前的程序上稍作修改或增加新的类,即可轻松增加许多程序功能。
以前开发的许多类可以重用,而程序结构根本不再需要改变,各类之间相互独立,便于团体开发,提高开发效率。
下面讨论如何实现一个模型、两个视图和一个控制器的程序。
其中模型类及视图类根本不需要改变,与前面的完全一样,这就是面向对象编程的好处。
对于控制器中的类,只需要增加另一个视图,并与模型发生关联即可。
该模式下视图、控制器、模型三者之间的示意图如图2所示。
同样也可以实现其它形式的MVC例如:
一个模型、两个视图和两个控制器。
从上面可以看出,通过MVC模式实现的应用程序具有极其良好的可扩展性,是ASP.NET面向对象编程的未来方向。
四、MVC的优点
大部分用过程语言比如ASP、PHP开发出来的Web应用,初始的开发模板就是混合层的数据编程。
例如,直接向数据库发送请求并用HTML显示,开发速度往往比较快,但由于数据页面的分离不是很直接,因而很难体现出业务模型的样子或者模型的重用性。
产品设计弹性力度很小,很难满足用户的变化性需求。
MVC要求对应用分层,虽然要花费额外的工作,但产品的结构清晰,产品的应用通过模型可以得到更好地体现。
首先,最重要的是应该有多个视图对应一个模型的能力。
在目前用户需求的快速变化下,可能有多种方式访问应用的要求。
例如,订单模型可能有本系统的订单,也有网上订单,或者其他系统的订单,但对于订单的处理都是一样,也就是说订单的处理是一致的。
按MVC设计模式,一个订单模型以及多个视图即可解决问题。
这样减少了代码的复制,即减少了代码的维护量,一旦模型发生改变,也易于维护。
其次,由于模型返回的数据不带任何显示格式,因而这些模型也可直接应用于接口的使用。
再次,由于一个应用被分离为三层,因此有时改变其中的一层就能满足应用的改变。
一个应用的业务流程或者业务规则的改变只需改动MVC的模型层。
控制层的概念也很有效,由于它把不同的模型和不同的视图组合在一起完成不同的请求,因此,控制层可以说是包含了用户请求权限的概念。
最后,它还有利于软件工程化管理。
由于不同的层各司其职,每一层不同的应用具有某些相同的特征,有利于通过工程化、工具化产生管理程序代码。
五、MVC的不足
MVC的不足体现在以下几个方面:
(1)增加了系统结构和实现的复杂性。
对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。
(2)视图与控制器间的过于紧密的连接。
视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。
(3)视图对模型数据的低效率访问。
依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。
对未变化数据的不必要的频繁访问,也将损害操作性能。
(4)目前,一般高级的界面工具或构造器不支持MVC模式。
改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,从而造成使用MVC的困难。
自己理解的J2EE三层架构(与软件设计模式的联系区别)
(2009-04-1309:
37:
50)
转载
标签:
软件设计模式
dao
j2ee
表示层
杂谈
如上图
1.J2EE分3层:
服务器端业务逻辑(有业务逻辑层和持久化数据层,BusinnessTier和EISTier)、服务器端表示层(WebTier)及客户端表示层(ClientTier)
可以将J2EE设计模式归纳到6个类别
(1)表示层体系结构模式(服务器端表示层)
a.前端控制器模式
b.MVC模式
c.装饰器模式
(2)表示层高级体系结构模式
a.复合视图模式(在服务器端表示层)
b.视图助手模式
c.服务工作者模式
(3)表示层伸缩性模式(服务器端表示层)
a.异步页面模式
b.缓存过滤器模式
c.资源池模式
(4)业务层模式(服务器端业务逻辑层)
a.复合实体模式
b.域对象模式(业务数据层)
(5)数据传递模式(用于业务逻辑层和表示层之间)
a.DTO模式
b.DTO传递散列模式
c.数据库行集合DTO模式
(6)数据库模式(服务器持久化数据层)
a.DAO模式
b.DAO工厂模式
2.前端控制器模式
常用的应用为,一个servlet作为一个前端控制器,它负责根据页面的请求,然后转发到页面控制器。
页面控制器也是一个servlet,这个servlet电泳关于这个请求所应该执行的业务逻辑,并根据业务逻辑的结果返回到具体的现实页面。
简化的使用是前端控制器servlet利用“命令模式”将页面控制器转化成一个个更细粒度的类。
AcitonServlet是前端控制器,部分代码
Requ