其实,就算用java建造一个不是很烦琐的web应用程序,也不是件轻松的事情。当为一个应用程序建造一个构架时有许多事情需要考虑。从高层来说,开发者需要考虑:怎样建立用户接口(user interfaces)?在哪里处理业务逻辑?和怎样持久化应用数据。这三层每一层都有它们各自的问题需要回答。 各个层次应该使用什么技术?怎样才能把应用程序设计得松耦合和能灵活改变?构架答应层的替换不会影响到其它层吗?应用程序怎样处理容器级的服务(container level services),比如事务处理(transactions)?
当为你的web应用程序创建一个构架时,需要涉及到相当多的问题。幸运的是,已经有不少开发者已经碰到过这类重复发生的问题,并且建立了处理这类问题的框架。一个好框架具备以下几点: 减轻开发者处理复杂的问题的负担(“不重复发明轮子”);内部定义为可扩展的;有一个强大的用户群支持。框架通常能够很好的解决一方面的问题。然而,你的应用程序有几个层可能都需要它们各自的框架。就如解决你的用户接口(UI)问题时你就不应该把事务逻辑和持久化逻辑掺杂进来。例如,你不应该在控制器(controller)里面写jdbc代码,使它包含有业务逻辑,这不是控制器应该提供的功能。它应该是轻量级的,代理来自用户接口(UI)外的调用请求给其它服务于这些请求的应用层。好的框架自然的形成代码如何分布的指导。更重要的是,框架减轻开发者从头开始写像持久层这样的代码的痛苦,使他们专注于对客户来说很重要的应用逻辑。
这篇文章将讨论怎样组合几个闻名的框架去做到松耦合的目的,怎样建立你的构架,怎样让你的各个应用层保持一致。富于挑战的是:组合这些框架使得每一层都以一种松耦合的方式彼此沟通,而与底层的技术无关。这篇文章将使用3种流行的开源框架来讨论组合框架的策略。表现层我们将使用Struts(http://jakarta.apache.org/struts);业务层我们将使用SPRing(http://www.springframework.org/);持久层使用Hibrenate(http://www.hibernate.org/).你也可以在你的应用程序中替换这些框架中的任何一种而得到同样的效果。图1展示了当这些框架组合在一起时从高层看是什么样子。
图1用Struts, Spring, 和 Hibernate框架构建的概览
应用程序的分层 (application Layering)
大多数不复杂的web应用都能被分成至少4个各负其责的层次。这些层次是:表现层(presentation)、持久层(persistence)、业务层(business)、领域模型层(domain model)。每层在应用程序中都有明确的责任,不应该和其它层混淆功能。每一应用层应该彼此独立但要给他们之间放一个通讯接口。让我们从审阅各个层开始,讨论这些层应该提供什么和不应该提供什么。
表现层 (The Presentation Layer)
在一个典型的web应用的一端是表现层。很多Java开发者也理解Struts所提供的。然而,太常见的是,他们把像业务逻辑之类的耦合的代码放进了一个org.apache.struts.Action。所以,让我们在像Struts这样一个框架应该提供什么上取得一致意见。这儿是Struts负责的:
为用户治理请求和响应;
提供一个控制器(controller)代理调用业务逻辑和其它上层处理;
处理从其它层掷出给一个Struts Action的异常;
为显示提供一个模型;
执行用户接口(UI)验证。
这儿是一些经常用Struts编写的但是却不应该和Struts表现层相伴的项目:
直接和数据库通讯,比如JDBC调用;
业务逻辑和与你的应用程序相关的验证;
事务治理;
在表现层中引入这种代码将导致典型耦合(type coupling)和讨厌的维护。
持久层 (The Persistence Layer )
在典型web应用的另一端是持久层。这通常是使事情迅速失控的地方。开发者低估了构建他们自己的持久层框架的挑战性。一般来说,机构内部自己写的持久层不仅需要大量的开发时间,而且还经常缺少功能和变得难以控制。有几个开源的“对象-关系映射”(ORM)框架非常解决问题。尤其是,Hibernate框架为java提供了"对象-关系持久化"(object-to-relational persistence)机制和查询服务。Hibernate对那些已经熟悉了SQL和JDBC API的Java开发者有一个适中的学习曲线。Hibernate持久对象是基于简单旧式Java对象(POJO)和Java集合(Java collections)。此外,使用Hibernate并不妨碍你正在使用的IDE。下面的列表包含了你该写在一个持久层框架里的代码类型:
查询相关的信息成为对象。Hibernate通过一种叫作HQL的面向对象(OO)的查询语言或者使用条件表达式API(eXPressive criteria API)来做这个事情。 HQL非常类似于SQL-- 只是把SQL里的table和columns用Object和它的fields代替。有一些新的专用的HQL语言成分要学;不过,它们轻易理解而且文档做得好。HQL是一种使用来查询对象的自然语言,花很小的代价就能学习它。
保存、更新、删除储存在数据库中的信息。
像Hibernate这样的高级“对象-关系”映射(object-to-relational mapping)框架提供对大多数主流SQL数据库的支持,它们支持“父/子”(parent/child)关系、事务处理、继续和多态。