用不是一个简单的任务。在架构这个应用时要考虑很多的因素和问题。从更高的层次来看,开发人员面临着关于如何构建用户接口,何处驻留业务逻辑,以及如何实
现数据持久性这些问题。这3层都有各自的问题需要回答。而每一层又需要实现那些技术?应用如何设计来进行松散耦合并能进行灵活变更?应用架构是否允许某一
层变更而不影响到其它的层次?应用应该如何处理容器一级的
支持它。框架通常能很好的解决一个问题。然而,你的应用是分层的,可能每一个层都需要各自的框架。仅仅解决UI问题并不意味着你能够很好的将业务逻辑和持
久性逻辑和UI 组件很好的耦合。例如,你不应该使具有JDBC代码的业务逻辑放入控制器之中,这不是控制器应该提供的功能。一个UI
控制器应该是轻量化的组件,由它代表对UI范围之外的其它应用层的服务调用。良好的框架自然地形成代码分离的原则。更为重要的是,框架减轻了开发人员从头
构建持久层代码的精力,从而集中精力来应用逻辑上,这对客户端来说更为重要。
本文讨论了如何结合几个著名的框架来达到松散耦合,如何设计你的架构,以及如何达到各个层次的一致性设计。面临的挑战是,将框架整合起来,以使
每一层都向另外的层次以一种松散的方式来暴露接口,而不管底层功能使用的是什么技术。本文还讨论整合3种著名开源框架的一种策略。对表现层,我们使用
Struts;业务层使用Spring;对于持久层我们使用的是Hibernate。你尽可以取代这里的某个框架而使用你喜欢的框架已达到同样的效果。图
1显示了框架被整合起来时,从最高层次看到的视图。
应用层
许多设计良好的web
表现层
一个典型的web 应用的末端是表现层。许多Java 开发者都知道Struts 提供了什么东西。然而,太多时候,耦合代码比如业务逻辑被放进org.apache.struts.Action中。所以,我们先总结一下Struts 之类的框架应该提供什么。下面就是Struts 的职责所在:
◆管理用户的请求和响应
◆提供一个控制起来将调用委托到业务逻辑和其他上游处理
◆将来自于抛出例外的其他层的例外处理到Struts Action 中
◆组装可以在视图中表现的模型对象
◆执行UI 校验
下面是一些经常可以使用Struts进行编码但是不应该和表现层关联的事情:
◆直接和数据库交互,比如JDBC 调用
◆与应用相关的业务逻辑和校验
◆事务管理
◆在表现层中引入这些类型的代码将导致类型耦合和维护负担。
持久层
一个典型Web应
用的另一端是持久层。这也是应用中最容易很快失控的地方。开发者通常低估了自己构建自己的持久层框架的挑战。一个定制的,内部开发的持久层不仅需要大量的
开发时间,并且通常缺乏功能和难以管理。目前有许多解决这些问题的开源对象关系映射 (ORM) 框架。特别地, Hibernate
框架就允许Java中的对象-关系的持久性和查询服务。Hibernate 对已经熟悉了SQL 和JDBC API
的Java开发者来或具有中度的学习曲线。Hibernate 的持久对象基于POJO和Java
群集(collections)。此外,使用Hibernate 不和你的IDE接口。下面列出了你需要在持久性框架中编写的代码类型:
高级的对象关系映射框架比如Hibernate支持大部分主流SQL数据库,它们支持父/子关系,事务,继承和多态。
下面是应该在持久层避免的一些事情:
◆业务逻辑应该置于应用的更高层中。这里只允许数据访问方法。
◆不应该使持久逻辑和表现逻辑耦合。避免表现组件如JSP
业务层
典型的Web
从编程的角度来说,service
layer经常被忽略。这种类型的代码散布于UI表现层和持久层并不是不多见。这些都不是正确的地方因为它导致了紧密耦合的应用和难以维护的代码。幸运的
是,大多数框架都解决了这个问题。这个空间内最流行的两个框架是Spring
和PicoContainer。它们都被视为是具有非常小的足迹(footprint)并且决定如何将你的对象整合在一起的微容器
(microcontainer)。这些框架都建立在一种叫做依赖性注入(dependency injection)
(也称控制反转(inversion of
control:IOC))的简单概念之上。我们将关注Spring中通过针对命名配置参数的bean属性的setter 注入的使用。Spring
也允许一种更加高级的构造器注入(constructor injection)形式作为setter injection
的可选替代。对象通过简单的XML 文件进行连接,该配置文件包含对各种对象的引用,比如事务管理
◆处理应用的业务逻辑和业务校验
◆管理事务
◆允许与其他层进行交互的接口
◆管理业务级对象之间的依赖性
◆加入了表现和持久层之间的灵活性,以便它们不需要彼此进行直接通信
◆从表现层暴露上下文给业务层以获得业务服务
◆管理从业务层到表现层的实现
领域模型层
最后,因为我们要解决实际的问题的web应
用,我们需要一套在不同的层间移动的对象。领域模型层包含的是表达实际业务对象的对象,比如Order, OrderLineItem,
Product 等等。这一层允许能让开发者不再构建和维护不必要的数据传输对象DTO来匹配其领域对象。例如,
Hibernate允许你读取数据库信息到一个领域对象的对象图中,以便你可以在离线的情况下将其表现在UI层中。这些对象可以被更新并跨过表现层发送回
去,然后进行数据库更新。另外,你不再需要将对象转变成DTO,因为它们在不同的层间移动时可能会丢失事务。这种模型允许Java 开发者能够以OO风格的方式很自然的处理对象,而不用编写额外的代码。