J2ee 集成层模式-数据访问对象
问题:
需要将数据访问及操作的逻辑封装在一个单独的层次中。
很多真实的J2EE应用系统将持久化对象实现为业务对象,具体的实现技术则可能是POJO或者 entity bean,如果应用系统需求更简单一些,也可以放弃业务对象,代之以会话门面、应用服务或者别的助手对象--这些助手对象将直接访问并操作持久化存储介质中的数据。不论是业务对象还是这些助手组件,他们都需要访问持久化存储中的业务数据。
通常情况下,大多数企业级应用会使用数据库管理系统作为持久化存储介质。但是企业数据也可能存在于别的地方,例如大型主机或者遗留系统、轻量级目录访问协议仓库、面向对象数据库、普通文件等等。另外,可以吧外部系统的服务所提供也视为持久化数据,这样的例子包括了B2B集成系统、信用卡机构的服务等等。
对于这些形形色色的持久化存储介质,他们的访问机制、支持的API和功能特性也是各不相同的。即便是遵从同一套API,底层的实现者也肯能在标准的特性之外在提供一些转有的扩展。
如果在持久化逻辑与应用逻辑混淆,就会直接导致应用程序直接依赖于持久化存储机制的实现。一旦在组件中出现这样的代码依赖,再想把应用程序从一种数据源移植到另一种数据源就会困难重重。当数据源发生变化时,组件也必须加以修改才能使用新的数据源。
约束:
--需要实现一个数据访问机制,用于访问、操作持久化存储介质中的数据。
--需要消除应用程序其余部分对持久化存储机制之间的耦合。
--需要为不同类型的数据源(例如:RDBMS、LDAP、OODB、XML仓库等)体统了一个统一的持久化机制和统一的数据访问API。
--需要对数据访问逻辑加以组织,并非标准点的专有特性封装起来,是系统便于维护和移植。
解决方案:
使用数据访问对象提炼,、封装持久化存储介质的访问数据访问对象负责管理与数据源的连接,并通过此链接获取、存储数据。
数据访问对象DAO实现了使用数据源所需的访问机制。不论使用哪种数据源,DAO总是想服务者提供统一的API,需要数据访问操作的业务组件只需要和DAO暴露给使用者的简单接口,DAO将数据源的实现细节完全的隐藏起来。当底层数据源实现发生变化时,DAO暴露给使用者的接口不用变化,因此可以放心的修改DAO的实现细节,也不会对DAO使用者造成任何的影响,从本质上来说,可以吧DAO看成是业务组件与数据源之间的一个适配器。
DAO应该被实现为无状态的对象。他不对任何的查询操作结果进行缓存。因此DAO是轻量级的对象,不存在出现线程同步问题的可能性。DAO封装了底层持久化API的细节。举例来说,当应用程序使用JDBC作为持久化手段时,DAO将所有对JDBC的使用都封装在数据访问层的内部,也不会向数据访问层之外的客户端暴露任何属于java.sql.* 或者javax.sql.*包的异常、数据结构、对象或者接口。
效果:
--用松耦合处理、程序集中控制
过滤器提供了一个处理多个请求的集中地方,其作用就像控制器。过滤器更适合处理一个目标源的多个处理程序的请求与答复。另外,控制器经常进行彼此不相关的日常服务、如验证、日志、加密等等。过滤器与处理器程序的关系不太紧张,因此可以用于各种场合。
--对持久化数据的透明访问
借助数据访问对象对数据源的封装,客户端可以透明的访问各种持久化存储介质,不必了解存储介质的位置和实现。
--为数据库数据结构提供了面向对象的视图和封装
客户端使用传输对象或者数据游标对象与数据访问对象交换数据,而不必依赖低层次的、与数据库数据结构相关的实现细节如果依赖这些实现细节,客户端就不得不了解数据库的表结构、字段名等信息。使用传输对象和数据游标,客户端可以用各一种面向对象的方式处理数据。
--简化数据移植
以DAO构成的数据访问层简化了应用程序在不同程序实现之间的移植。客户端无须了解底层的数据存储实现,因此移植动作只对DAO产生影响。
--降低了客户端的复杂度
DAO封装了所有与持久化的介质交互的代码,客户端只需使用数据访问层提供的简单API即可,这降低了客户代码执行数据访问的复杂度,提高了可维护性和开发效率。
--将所有的数据访问代码组织到一个单独的层中
数据访问对象吧实现数据访问功能的代码都组织到一个独立的层次中,将应用程序的其他部分与持久化存储介质和外部的数据源分开。由于所有数据访问操作都委派给DAO,这个层次就隔离了应用程序的其余部分和数据访问的实现。将数据访问操作集中在一个层次,使得应用程序更容易维护和管理。
--增加了一个层次
--需要设计整个类层次
--面向对象设计增加了复杂度