.NET 业务框架开发实战之六 DAL的重构

转载 2012年03月15日 16:49:26
 前言:其实这个系列还是之前的".NET 分布式架构开发实战 ",之所以改了名字,主要是因为文章的标题带来了不少的歧义:系列文章中本打算开发一个简化业务发的流程的Framework,然后用这个Framework再来实战,开发一个分布式的应用。改了名字。给大家带来了不便,敬请见谅。

   本篇的议题如下:
   1. 确定DAL的接口的定义。

 之前在开发DAL中,提出了一些思想,也设计了一些接口。现在就把DAL的一些设计完善起来。说是“完善”,并不是说把所有的代码都实现,而是把该定义的接口,方法敲定下来。Richard认为,设计一个架构或者Framework的时候,开始是接口的定义,定义好各层之间交互的接口,然后才是具体代码的实现。


   因为在设计Framework的时候,首先要考虑这个Framework的使用者是谁,希望他们怎么样来使用开发出来的这个Framework。在这里,Richard很明白:Framework的使用者就是自己公司里的开发人员。而且还要使得开发的使用尽量的方便,不要到处去配置一些文档,最好就是把Framework引入进来,稍微配一下就使用。

 

  在Richard设计的Framework中,就DAL而言,如果希望DAL返回DataTable,DataReader等给BLL,那么需要配置的仅仅只是指明数据库的连接字符串;如果希望DAL返回的数据实体给BLL,那么就得把一张张的表映射成为实体,然后让这些实体继承IDataEntity接口就行了(生成实体可以用ORM工具,或者自己手写代码)。

 Richard思考了之前对DAL的设计,在此他做了一些改进。


   首先就是对于IDataContext的重新设计和理解:之前的设计是定义了IDataContext,然后用不同的方式实现这个接口,如LinqDataContext.Provider就是用Linq的方法来返回结果(DataResult)。现在Richard认为IDataContext其实就是用来操作数据库的,所以返回的结果就应该是操作数据之后的结果,如Update操作就返回受影响的行数或者是否更新成功。至于是否要把一些额外的信息包装返回给BLL,就不是IDataContext的实现者的事情了。而且Richard还考虑到了需要在一定程度上支持原生的ADO.NET,起码给ADO.NET预留接口。

 

   基于此,Richard就把IDataContext定义为一个接口声明,然后再定义了IDataEntityContext,和IDataTableContext来继承IDataContext,他们的关系图如下:

  

  

   其中IDataEntityContext使用Linq和Entity Framework来实现,而IDataTableContext就是用ADO.NET的方式来实现。

    IDataEntityContext接口的和系列文章中定义的一些方法差不多,但是做了修改。其中有一点要提的就是:ICriteria就是所有条件对象要实现的接口(查询对象也是条件对象的一种)。例如,可以根据相应的条件删除,更新数据。

/// <summary>
    
/// 所有的数据实体执行者实现这个借口
    
/// </summary>
    public interface IDataEntityContext:IDataContext
    {
        TEntity Add<TEntity>(TEntity entity) where TEntity : IDataEntity;
        List<TEntity> Add<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;

        
bool Update<TEntity>(TEntity entity) where TEntity : IDataEntity;
        
bool Update<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
        
bool Update(ICriteria condiftion, object value);

        
bool Delete<TEntity>(TEntity entity) where TEntity : IDataEntity;
        
bool Delete<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
        
bool Delete(ICriteria condition);

        
int GetCount(ICriteria condition);
        List<TEntity> Query<TEntity>(ICriteria condition);
        List<TEntity> Query<TEntity>(ICriteria condition, int pageIndex, int pageSize, ref int entityCount) where TEntity : IDataEntity;
        List<object> Query(ICriteria condiftion);
    }

另外就是多了一个 List<object> Query(ICriteria condiftion);方法,之所以有这个方法,Richard考虑到,可能开发人员想要直接自己写SQL语句去执行,如select avg(Count),sum(Name) from Customer...,开发人员可以写任意的语句,所以返回一个实体类不现实,就返回一个List<object>。

 

   还有一点就是关于查询对象的改进:以前仅仅只是定义了查询对象的接口,现在用ICriteria 接口中定义来条件对象,而且还可以在条件对象声明是在对数据操作是否采用事务或者缓存。

/// <summary>
    
/// 所有的条件对象都要从这个接口继承
    
/// </summary>
    public interface ICriteria
    {
        
string Name { getset; }
        
bool IsCache { getset; }
        
bool IsTransaction { getset; }
    }

之后Richard又定义了一个IDataProvider,接口,声明如下 :

/// <summary>
    
/// 数据提供者要实现的借口
    
/// </summary>
    public interface IDataProvider
    {
        DataResult<TEntity> Add<TEntity>(TEntity entity) where TEntity : IDataEntity;
        DataResult<TEntity> Add<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;

        DataResult<TEntity> Update<TEntity>(TEntity entity) where TEntity : IDataEntity;
        DataResult<TEntity> Update<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
        
bool Update(ICriteria condiftion, object value);

        DataResult<TEntity> Delete<TEntity>(TEntity entity) where TEntity : IDataEntity;
        DataResult<TEntity> Delete<TEntity>(List<TEntity> entityList) where TEntity : IDataEntity;
        
bool Delete(ICriteria condiftion);

        
int GetCount(ICriteria condition);

        DataResult<TEntity> GetOne<TEntity>(ICriteria condition) where TEntity : IDataEntity;
        DataResult<TEntity> GetList<TEntity>(ICriteria condition) where TEntity : IDataEntity;
        DataResult<TEntity> GetPageData<TEntity>(ICriteria condition, int pageIndex, int pageSize, ref int entityCount) where TEntity : IDataEntity;
        List<object> GetCustomData(ICriteria condiftion);
    }

 之所以要定义这个接口,其实 Richard就是想让实现了IDataContext的类踏踏实实的去做底层的数据操作,至于数据操作之后的结果以什么形式给BLL,不用IDataContext的实现者来关心,而是用IDataProvider的实现者来关心。


   在IDataProvider的实现者在底层就是调用了IDataContext的实现者的方法,然后在IDataProvider中,对外提供了一些更加友好和方便使用的方法,最后在BLL中直接依赖的就是IDataProvider,而不是IDataContext。


   另外,对于IDataProvider返回的DataResult也做了一些修改:如果返回的是数据实体,即 使用的是IDataEntityContext来提供底层的数据操作,那么DataResult<TEntity>是没有问题的;但是如果使用的是IDataTableContext,那么返回DataResult<TEntity>就不行了,因为IDataTableContext查询方法可能返回的DataTable,或者DataReader.所以,在设计中叶预留了一个接口:让IDataProvider返回的结果实现IDataResult接口,那么ataResult<TEntity>继承这个接口,主要用来返回数据实体,如下:
 

   

  DAL的设计就到这里,下一篇文章就开始讲述对业务层的一些思考。

  版权为小洋和博客园所有,转载请标明出处给作者。

    http://www.cnblogs.com/yanyangtian

   代码下载  

 

.NET 业务框架开发实战

.NET 分布式架构开发实战之一 故事起源     前言:本系列文章主要讲述一个实实在在的项目开发的过程,主要包含:提出问题,解决问题,架构设计和各个逻辑层的实现以及新问题的出现和代码的重构。本系...
  • E_eric
  • E_eric
  • 2013年06月04日 22:26
  • 660

实体框架- Entity Framework 基础篇

以前写数据层D层的时候里面有好多的SQL语句,如何省略到繁琐的SQL语句,微软提供了一种很好的方式-实体框架-Entity Framwork。一种对象映射机制,支持.NET开发人员使用域特定对象来出来...
  • lxy344x
  • lxy344x
  • 2015年05月09日 08:16
  • 2366

初涉三层架构,UI层和DAL层的调用,ADO.NET对数据库的数据增删改

UI层:可以说是界面层吧
  • Real_young
  • Real_young
  • 2015年05月15日 13:23
  • 2534

ASP_NET的三层架构(DAL,BLL,UI)

ASP.NET的三层架构(DAL,BLL,UI)  ASP.NET的三层架构(DAL,BLL,UI) BLL   是业务逻辑层   Business   Logic   Layer   DAL   是...
  • hatchgavin
  • hatchgavin
  • 2011年03月14日 15:51
  • 7017

关于开源.NET代码中文件夹 DAL+IDAL+Model+BLL+Web

近期学习.NET技术,下载了很多开源系统进行研究,发现里边有很多文件夹,编译后只有一个网站目录。原来网站开发采用的是三层架构。三层架构是一个程序最基本的 在.Net开发中通常是多层开发。 比如说...
  • u011551072
  • u011551072
  • 2014年09月22日 10:37
  • 612

在.NET中DAL+IDAL+Model+BLL+Web

在.NET中 DAL+IDAL+Model+BLL+Web 业务逻辑层(BLL):主要是针对具体的问题的操作,也可以理解成对数据层的操作,对数据业务逻辑处理。如果说数据层是积木,那逻辑层就是对这些积...
  • mobiyue
  • mobiyue
  • 2014年05月07日 16:26
  • 1324

ASP.NET三层架构DAL层连接数据库的方法

 【转自】 http://zhidao.baidu.com/question/100925344.html --问题:ASP.NET三层架构DAL层连接数据库的方法本人初步接触ASP三层,我知道如果在...
  • gxj022
  • gxj022
  • 2009年08月18日 20:21
  • 1894

Java用观察者模式重构复杂的业务代码

1. 定义一个统一的回调接口 public interface CallerInter { void call(Param param); } 2. 定义观察者接口 public inte...
  • u011734144
  • u011734144
  • 2016年08月19日 16:50
  • 725

如何重构一个系统

如何重构一个系统 发现一个很有意思的情况,做系统写代码多年了,遇到的需求基本上是在已有的系统上实现,从头来实现的系统基本上没有。 1 why 无论是从头是实现一个系统,还是维护一个系统,当时实现的技术...
  • liu251
  • liu251
  • 2014年12月21日 13:52
  • 5036

产品架构重构与优化

大规模软件系统的产品周期 随着产品的不断发展,复杂度不断增加,生产率(Features数量)下降,质量(Bugs)不受控制,稳定性(Fluctuation)变差,架构变得腐化。 原则、...
  • wilbertzhou
  • wilbertzhou
  • 2014年09月23日 20:48
  • 1023
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.NET 业务框架开发实战之六 DAL的重构
举报原因:
原因补充:

(最多只允许输入30个字)