假设
      1)你跟我一样在某种程度上不能容忍“智能UI”的开发方式。
      2)你跟我一样同样不能容忍持久层掺杂进任何的业务逻辑
      3)你跟我一样在面向对象数据技术彻底成熟之前,总是优先倾向于ORM,而不是直接书写SQL语句来完成对象持久相关的工作,你总是认为数据库就是个仓库而已。

      一直以来我对关系数据库总是爱恨交加。最让我烦躁的是,总是不得不把一些业务逻辑放到数据库中去,哪怕就这么一点原因,也足以让我非常非常的不爽。这其中又有两个典型的场景。
      场景一:通过查询条件来获取列表。在这种情况下,有这么一种比较典型的设计,代码类似下面的样子:      

 1/// <summary>
 2        /// 扩展查询机构信息(模糊查询)
 3        /// </summary>
 4        /// <param name="orgName">机构名称片断</param>
 5        /// <param name="orgType">机构类型</param>
 6        /// <param name="isAuthorize">是否授权</param>
 7        /// <param name="orderName">排序字段名称</param>
 8        /// <param name="isASC">是否升序</param
 9        /// <param name="pagingInfo">分页信息</param>
10        /// <returns>机构列表</returns>

11        IList<Organization> GetOrgInfoListByMultiField(string orgName, OrgType orgType, bool? isAuthorize,
12                                                       string orderName, bool isASC, PagingInfo pagingInfo);

这个方法所在的接口,放在了领域层内,但是接口的实现是在数据访问层。在这种场景下面,如果是仅仅单表的查询,还不是最糟糕的,起码各种各样的参数还标明了领域层的印记。最糟糕的是查询里面隐藏了很强的业务逻辑
      场景二:获取在某个项目中,没有参与投标的企业列表(申报的产品数量为0)。在这种情况下,我同样可以设计一个接口方法,象上面的一样,提供一个ProjectId来进行查询。但是申报的产品数量为0这个显而易见的领域逻辑,就以一种令人生厌的Sql形态高度耦合到持久层了。

      我很难想象这种原本属于领域层的逻辑大量的以查询的方式散落到持久层会对业务相对复杂的系统产生的不良影响。令人欣慰的是ORM技术越来越成熟,显然他们针对这个问题做出了一些努力。比如在Nhibernate中提供了HQL,我们可以使用HQL来进行面向对象的查询,通过NHibernate的支持来满足类似上述这两种场景的需求。但是,仅仅是这样,还不够。HQL本质上还是字符串,我们无法象静态类型一样来保证我们的类型安全,保证编译期间排除错误
      
      于是,强类型查询出现了。请看下面的类似代码:      

1var q2 = (from o in db.Orders
2                 where !(new string[] "AROUT""BOLID""FISSA" }).Contains(o.CustomerID)
3                 select o).ToList();

      强类型在HQL之外,给我们带来了更直观,更强壮的查询。这使得我们从本质上可以用相对优雅的方式完全把领域和它的仓库隔离开来(抛开诸如效率,学习曲线,领域建模这些问题先不谈)。我们可以这样理解强类型的查询,用我们熟悉的类型安全的代码方式来表达我们的业务逻辑,然后交给支持强类型的服务去执行。
领域层依赖于持久层提供的服务,但是聚合了领域范围内有实际意义的业务逻辑。
      通过相关的ORM技术(这种技术支持强类型查询,至少也要支持一套描述标准SQL的查询规则)以及相应的配套工具,剥离领域层和持久层的强关联,可以使我们更专心于业务的本身。 

      期待着相对屏蔽数据库的开发时代到来……              

posted on 2007-08-30 14:55  Loris  阅读(2219)  评论(26编辑  收藏  举报