框架通常是代码重用,设计模式是设计重用,架构则介于两者之间。
5.1 MVC模式概述
MVC是一种架构式模型,它本身并不引入新的功能,只是用来指导改善应用程序的架构,使得应用的模型和视图相分离,从而得到更好的慨法赫维护效率。
5.1.1 MVC模式简介
M是指数据模型,V是指用户界面,C是指控制器,从设计模式的角度看,MVC是一种复合模式,它将多个设计模式在一种解决方法中结合起来,用来解决许多设计问题。
MVC模式把用户界面程序交互拆分到3种不同的角色中,使应用程序被划分为3个核心部件:Model、View、Control,他们各自处理自己的任务。使用MVC的目的是将M和V的实现代码分离,使得同一个程序可以使用不同的表现形式。比如,一批数据可以分别用柱状图、饼图表示。C存在的目的是确保M和V的同步,一旦M改变,V也同步更新,三部分职责明确,而且相互分离,因此各个部分都可以独立改变而不影响其他部分。
MVC中视图的作用是将程序运行的结果呈现给用户,模型的作用则是实现用户的逻辑,主要是接收用户的参数,完成一些运算,以及访问数据库。MVC是一种思想,是一种横向的分层,java EE中的MVC更加成熟,结构更加合理,再加上java的特点(优越的跨平台性),可以利用MVC构建出强大的集群系统。
5.1.2 MVC模式基础
1.模型、视图和控制器
MVC是一个设计模式,它强制性地使应用程序的输入、处理和输出分开。
(1)模型
模型负责封装应用的状态,并实现应用的功能,封装的是数据源和所有基于这些数据的操作。在一个组件中,模型往往表示组件的状态和操作状态的方法。模型通常又分为数据模型和业务逻辑模型,数据模型用来存放业务数据,如订单信息、用户信息等;而业务逻辑模型包含应用的业务操作,如订单的添加或者修改等。模型表示企业数据和业务规则。
在MVC的3个部件中,模型拥有最多的处理任务。例如,它可能用EJBs和ColdFusion Components这样的的构件对象来处理数据库。被模型返回的数据是中立的,也就是说模型与数据格式无关,这样一个模型能为多个视图提供数据,所以应用于模型的代码只需写一次就可以被多个视图重用。
(2)视图
视图用来将模型的内容展现给用户,用户可以通过视图来请求模型进行更新,封装的是对数据源Model的一种显示。一个模型可以有多个视图,而一个视图理论上也可以与不同的模型关联起来。视图从模型获得要展示的数据,然后用自己的方式展现给用户,相当于提供界面来与用户进行人机交互;用户在界面上操作或者填写完成后,会单击提交按钮或是以其他触发事件的方式来向控制器发出请求。
在视图中其实没有真正的处理发生,不管这些数据是联机存储的还是一个雇员列表,作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式。
(3)控制器
控制器用来控制应用程序的流程和处理视图所发出的请求,封装的是外界作用于模型的操作。通常这些操作会转发到模型上,并调用模型中相应的一个或多个方法。一般控制器在模型和视图中起到了沟通的作用,处理用户在视图上的输入并转发给模型。这样模型和视图两者之间可以做到松散耦合,甚至可以彼此不知道对方,而由控制器连接这两个部分。
当控制器接收到用户的请求后,会将用户的数据与模型的更新相映射,也就是调用模型来实现用户请求的功能;然后控制器会选择用于响应的视图,把模型更新后的数据展示给用户。控制器接受用户的输入并调用模型和视图去完成用户的需求。所以当单击web页面中的超链接和发送html表单时,控制器本身不输出任何东西,也不做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后确定用哪个视图来显示模型处理返回的数据。
2.MVC的组件关系
MVC的处理过程是,首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。
MVC组件关系图:
下面按照交互顺序再详细描述一下他们的交互信息:
1)首先是展示视图给用户,用户在这个视图上进行操作并填写一些业务数据
2)然后用户会单击提交按钮来发出请求
3)视图发出的用户请求会到达控制器,在请求中包含了想要完成什么样的业务功能及相关的数据
4)控制器会处理用户请求,把请求中的数据封装,然后选择并调用合适的模型,请求模型进行状态更新,并选择接下来要展示给用户的视图
5)模型会去处理用户的业务功能,同时进行模型状态的维护和更新
6)当模型状态发生改变时,模型会通知相应的视图,告诉视图其状态发生了改变
7)视图接到模型的通知后,会向模型进行状态查询,获取需要展示的数据,然后按照视图本身的展示方式将这些数据展示出来
5.1.3 MVC模式的作用
大部分web应用程序都是用过程化语言来创建的,他们将像数据库查询这样的数据层代码和像html这样的表示层代码混在一次。MVC从根本上强制性地将他们分开。尽管构造MVC应用程序需要一些额外工作,但是它给用户带来的好处是毋庸置疑的。
首先最重要的是多个视图能共享一个模型。现在需要用越来越多的方式来访问应用程序,对此,使用MVC可以解决,无论用户想要的是Flash界面还是WAP界面,用一个模型就可以处理他们。
由于模型返回的数据没有进行格式化,所以同样的构件能被不同界面使用。模型也有状态管理和数据持久化处理的功能,例如,基于会话的购物车和电子商务过程也能被Flash网站或者无线联网的应用程序所重用。‘因为模型是自包含的,并且与其他两部分分离,所以很容易改变应用程序的数据层和业务规则。如果想把数据库从mysql移植到oracle,或者改变基于RDBMS数据源到LDAP,,只需改变模型即可。
另外,控制器还有一个好处就是可以连接不同的模型和视图去完成用户的需求,为构造应用程序提供强有力的手段。给定一些可重用的模型和视图,控制器可以根据用户的需求选择模型。
MVC不适合小型甚至中等规模的应用程序,适合在大规模应用程序上发挥作用。
MVC模式的核心手段是解耦,使用它可以获得以下好处:
1)低耦合性;2)更低的开发成本;3)更好的可维护性
MVC模式广泛应用于web程序和GUI程序的架构,主要优点如下:
1)具有多个视图对应一个模型的能力
2)有时改变其中的一层就能满足应用的改变
3)控制层的管理能力更加有效
4)有利于软件工程化管理
MVC的不足主要体现在下面几个方面:
1)增加了系统结构和实现的复杂性
2)视图与控制器间联系紧密
3)视图对模型数据的低效率访问
4)一般高级的界面工具或构造器不支持MVC模式
5.1.4 java EE中的MVC
MVC是一种横向分层的思想,采用这种思想可以构建出各种系统。前面讲过的三层架构模式与MVC模式是两个概念。三层架构分为表示层、逻辑层和持久层,其中表示层是术语web方面的开发,对应于MVC的视图和控制器,Java EE中的过滤器也属于表示层,,虽然他和表示没有什么关系,但是它的实现技术是一种横切技术,将request的请求进行过滤然后传到控制器,控制器根据需要调用业务逻辑和视图展示给用户。逻辑层和持久层是为了程序的可移植性,把MVC中的模型层分为专门用于计算的逻辑层和专门访问数据的持久层。业务逻辑层主要是Javabean实现,而持久层最常见的就是DAO(data access object),封装了数据库的所有操作,从结构来说,三层结构是纵向的分层,上层依赖于下层,下层不依赖于上层,即单向依赖。
两者可以灵活进行组合设计:JSP+JavaBean(sun的Model1)、MVC+1(横向按MVC,纵向一层——Servlet直接访问数据、库)、MVC+2(横向按MVC,纵向两层——Servlet调用逻辑层访问数据库)、MVC+3(横向按MVC,纵向三层——Servlet调用业务逻辑,业务逻辑访问数据库)。
Java EE中的视图一般使用MVC,当然也可以使用HTML+AJAX技术实现一个交互性高的异步通信web应用。模型层是以JavaBean为主体,实现java的业务逻辑;控制器则是用Servlet实现,这样整体来说java EE为不同的角色提供了不同的标准。
在java的web开发中,通常把Servlet+JSP+JavaBean的模型称为Model2模型,基本划分如下:
1)JavaBean作为模型,既可以作为数据模型来封装业务数据,又可以作为业务逻辑模型来包含应用的业务操作。其中,数据模型用来存储或传递业务数据,而业务逻辑模型接收到控制器传过来的模型更新请求后,执行特定的业务逻辑处理,然后返回相应的执行结果。
2)JSP作为表现层,负责提供页面为用户展示数据,提供相应的表单来响应用户的请求,并在适当的时候向控制器发送用户请求来要求模型进行更新。
3)Servlet作为控制器,用来接收用户提交的请求,并获取请求中的数据,将之转换成业务模型需要的数据模型,然后调用业务模型相应的业务方法,请求模型进行更新,同时根据业务执行结果选择要返回的视图,也就是选择下一个页面。
(此图来源于网上,侵删)
5.2 框架的概念
框架是在给定的问题领域内的一个应用程序的部分设计与实现,它定义了一类应用系统或子系统的整体结构。框架将应用系统划分为类和对象,并定义类和对象的责任、类和对象如何互相协作,以及对象之间的之间的控制线程。
框架和工具包的不同之处在于,框架提供了一致的结构而不仅仅是一组工具类,是一个可复用的开发规范。很多情况下,框架通常以构件库的形式出现,但这只是框架的一部分,框架的关键还在于框架内对象间的交互模式和控制流模式。框架比构件可定制性强,框架为构件提供重用的环境,为构件处理错误、交换数据及激活操作提供了标准的方法。
5.3 主流框架介绍
5.3.1 Struts框架
Struts是Apache软件基金会(ASF)赞助的一个开源项目。它最初是Jakarta项目中的一个子项目,并在2004年3月成为ASF的顶级项目。它通过采用Java Servlet/JSP技术,实现了基于Java EE Web应用的Model-View-Controller(MVC)设计模式的应用框架,是MVC经典设计模式中的一个经典产品。
在Struts中,已经由一个名为ActionServlet的Servlet充当控制器(Controller)的角色,根据描述模型、视图、控制器对应关系的struts-config.xml的配置文件,转发视图(View)的请求,组装响应数据模型(Model)。在MVC的模型(Model)部分,经常划分为两个主要子系统(系统的内部数据状态与改变数据状态的逻辑动作),这两个概念子系统分别具体对应Struts里的ActionForm与Action两个需要继承实现超类。在这里,Struts可以与各种标准的数据访问技术结合在一起,包括Enterprise Java Beans(EJB),JDBC与JNDI。在Struts的视图(View)端,除了使用标准的JavaServer Pages(JSP)以外,还提供了大量的标签库使用,同时也可以与其他表现层组件技术(产品)进行整合,比如Velocity Templates,XSLT等。通过应用Struts的框架,最终用户可以把大部分的关注点放在自己的业务逻辑(Action)与 映射关系的配置文件(struts-config.xml)中。
5.3.2 Hibernate框架
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JaveEE架构中取代CMP,完成数据持久化的重任。
- 将对数据库的操作转换为对Java对象的操作,从而简化开发。通过修改一个“持久化”对象的属性从而修改数据库表中对应的记录数据。
- 提供线程和进程两个级别的缓存提升应用程序性能。
- 有丰富的映射方式将Java对象之间的关系转换为数据库表之间的关系。
- 屏蔽不同数据库实现之间的差异。在Hibernate中只需要通过“方言”的形式指定当前使用的数据库,就可以根据底层数据库的实际情况生成适合的SQL语句。
- 非侵入式:Hibernate不要求持久化类实现任何接口或继承任何类,POJO即可。
5.3.3 Spring框架
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
◆目的:解决企业应用开发的复杂性
◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
◆范围:任何Java应用
Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。
控制反转——Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。
所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。
5.3.4 JSF框架
JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架(是Java Community Process 规定的JSR-127标准)。它提供了一种以组件为中心的用户界面(UI)构建方法,从而简化了Java服务器端应用程序的开发。由于由Java Community Process (JCP) 推动,属于Java EE 5中的技术规范,而受到了厂商的广泛支持。它是一种页面表示技术。
引入了基于组件和事件驱动的开发模式,使开发人员可以使用类似于处理传统界面的方式来开发Web应用程序。提供了行为与表达的清晰分离。 不用特别的脚本语言或者标记语言来连接UI组件和Web层。JSF技术API被直接分层在Servlet API的顶端。 技术为管理组件状态提供一个丰富的体系机构、处理组件数据、确认用户输入和操作事件。
典型的JSF应用程序包含下列部分:
- 一组JSP页面
- 一组后台bean(为在一个页面上的UI组件定义的属性和函数的JavaBean组件)
- 应用程序配置资源文件(定义页面导航规则、配置bean和其它的自定对象,如自定义组件)
- 部署描述文件(web.xml)
- 一组由应用程序开发者创建的自定义对象(有可能)
- 一些可能包含自定义组件、约束、转换器或者监听器的对象
- 为在页面中表现自定义对象的一组自定义tag
包含JSP页面的JSF应用程序也使用由为了表现UI组件和在页面上的其他对象的JSF技术而定义的标准的tag库。
这些框架会在后面分章节详细介绍,这里只是大致了解即可。