通过更换数据层无法解决问题的时候我们最多只需要更换业务数据访问层,而无需改变业务层。
业务数据访问层由DAO(Data Access Object)层和系统服务层两部分组成。DAO层为每个业务实体提供最基本的数据访问服务,
系统服务层为系统全局提供与业务关系不大的通用数据访问服务,这两层处于系统中的
同一个层次位置。
业务层与业务数据访问层关系图
数据层
数据层的宗旨就是为数据源提供一个可供外界访问的接口,我们应该选用一种能够提供数据源无关的抽象数据访问接口并通过在其下挂接各种不同的DataProviador来访问数据源的数据层组件,这样做便于移植到不同的数据源上。目前有以下3种数据层
方案:
1. 封装ADO.Net
这些数据访问组件都是基于ADO.Net的浅封装,它的优点在于封装层次低所以速度最快,我们可以手动组织sql语句用来适应复杂的操作以及个性的优化等。缺点是无法直接处理自定义数据实体方式的业务实体对象,需要将业务实体中的数据属性以参数形式传入传出。这样的方式虽然最为保险,但随着系统规模增大,开发效率,质量,,后期的维护,二次开发都变成尤为突出的
问题,对开发人员的要求会变的越来越高。另外对于事物操作封装不是很好,无法提供声明性事物,经常会在业务层出现访问数据层的需要。这样的组件目前应用的很广泛,例如微软在EnterpriseLibrary中提供的DAAB(Data Access Application Block),还有以前的DAAB3.1。EnterpriseLibrary是个成熟的产品,包括了数据访问,异常,日志,缓存,加密,配置,安全等组件做为通用服务非常适合。
2. OR-Mapping组件
ORM是最好的数据持久解决方案,它的优点在于能够以面向对象的方式操纵数据,因此可以直接处理自定义数据实体的业务对象,我们根本不用操心sql语句以及底层存储方式,这样极大的简化的代码提高了开发效率,对于日后维护扩展都带来极大的便利。缺点在于屏蔽了底层使得我们无法针对具体数据源做优化,而且对于复杂关联的
sql操作有些力不从心,同时性能也差一些但辅助以缓存情况会好很多,而在dotNet下最大的问题就是没有一个成熟便宜的ORM产品供我们使用,全部都是beta版本和商业版本。这些版本或多或少都存在一些问题,以至于真正应用中需要经过仔细考察。例如NHibernate,Gentle.Net,XPO,Grove.Net等等非常多。
3. DataMapper(SqlMapper)
SqlMapper为以上两种方式提供了一个折中的选择,它可以以面向对象的方式直接处理自定义数据实体的业务对象,同时可以根据与数据源与业务实体的映射关系执行手写的sql语句,这样完全使得我们可以针对具体数据源做优化,对于复杂操作同样可以胜任。目前只有iBatis.Net一个产品,它是一个java移至的开源项目,已经比较成熟,可以在无需编译的情况下随意替换DAO。
各层间的依赖关系
依赖关系图:
在对各层的讨论之后,我们来总结一下各层间的依赖关系
。说到依赖就离不开复用这个词,复用对软件开发流程的几乎每个阶段都有着重要的意义。在设计阶段它代表着更清晰的设计,在开发阶段它代表着更高的工作效率和代码质量,在测试阶段它代表着更轻易的捕获bug,在维护和再开发阶段它代表着更小的工作量。更好的复用需要设计更好的依赖关系。
从图中可以看出表示层与业务数据访问层都依赖于业务层,而业务层是相对独立的,这样设计的优点就是最大限度的减少了变动对整个系统所带来的影响。最坏的情况就是业务的改变,业务改变其他依赖业务层的地方必须改变(在这里我们忽略了一些针对多种业务而设计的其他层组件,这些组件是可以适应有限的业务变更而本身不用变更的。),这个我们没有办法控制。但像表示层与业务数据访问层等其他