随笔 - 48, 文章 - 4, 评论 - 332, 引用 - 20
数据加载中……

一个分层架构设计的例子(1)

一般来说,对系统的分层,一般都需要下面几个层:实体层(Entity)、数据访问层(DAL)、业务逻辑层(BLL)、界面层(UI);而数据访问层,一般也会加入一个接口层(IDAL)。
在其中的实体层,一般是根据数据库进行映射外加入注释等,技术含量不大,在此一笔带过;数据库访问层和业务逻辑层,是关键之所在,因为这里好的设计,会利用很多基类的操作,减少很多代码和重复劳动;界面层,不管是WebForm还是WinForm,都是尽可能少的逻辑代码或者SQL语句在其中,好的项目可能会利用一些优秀的控件进去,提高体验,减少代码。另外,由于一些创建操作费时费资源,一般还需要把可重复利用的资源缓存起来,提高性能。
先给大家预览下项目的框架,再一层层分析讨论:
EnterpriseLib.jpg

1、 实体层(定义一个空的基类,其他实体类继承之,主要是为了利用泛型操作,用途下面细说)
    public class BaseEntity
    
{    
    }

    public class EquipmentInfo : BaseEntity
    
{    
        
Field Members

        
Property Members

    }

2、 数据库访问层,数据访问层的关键是数据访问基类的设计,基类实现大多数数据库的日常操作,如下:

    /// <summary>
    
/// 数据访问层的基类
    
/// </summary>

    public abstract class BaseDAL<T> : IBaseDAL<T> where T : BaseEntity, new()
    
{
}

BaseEntity就是实体类的基类,IBaseDAL是定义的数据访问基类接口,包含各种常用的操作定义;因此BaseDAL就是要对各种操作的进行实现,实现接口越多,将来继承类的重用程度就越高。
以上通过泛型<T> ,我们就可以知道实例化那个具体访问类的信息了,可以实现强类型的函数定义。

    /// <summary>
    
/// 一些基本的,作为辅助函数的接口
    
/// </summary>

    public interface IBaseDAL<T> where T : BaseEntity
    
{
        
/// <summary>
        
/// 查询数据库,检查是否存在指定键值的对象
        
/// </summary>
        
/// <param name="recordTable">Hashtable:键[key]为字段名;值[value]为字段对应的值</param>
        
/// <returns>存在则返回<c>true</c>,否则为<c>false</c></returns>

        bool IsExistKey(Hashtable recordTable);

        
/// <summary>
        
/// 查询数据库,检查是否存在指定键值的对象
        
/// </summary>
        
/// <param name="fieldName">指定的属性名</param>
        
/// <param name="key">指定的值</param>
        
/// <returns>存在则返回<c>true</c>,否则为<c>false</c></returns>

        bool IsExistKey(string fieldName, object key);

        
/// <summary>
        
/// 获取数据库中该对象的最大ID值
        
/// </summary>
        
/// <returns>最大ID值</returns>

        int GetMaxID();

        
/// <summary>
        
/// 根据指定对象的ID,从数据库中删除指定对象
        
/// </summary>
        
/// <param name="key">指定对象的ID</param>
        
/// <returns>执行成功返回<c>true</c>,否则为<c>false</c></returns>

        bool DeleteByKey(string key);
        
        
/// <summary>
        
/// 根据条件,从数据库中删除指定对象
        
/// </summary>
        
/// <param name="condition">删除记录的条件语句</param>
        
/// <returns>执行成功返回<c>true</c>,否则为<c>false</c></returns>

        bool DeleteByCondition(string condition);


        
/// <summary>
        
/// 插入指定对象到数据库中
        
/// </summary>
        
/// <param name="obj">指定的对象</param>
        
/// <returns>执行成功返回True</returns>

        bool Insert(T obj);

        
/// <summary>
        
/// 更新对象属性到数据库中
        
/// </summary>
        
/// <param name="obj">指定的对象</param>
        
/// <returns>执行成功返回<c>true</c>,否则为<c>false</c></returns>

        bool Update(T obj, string primaryKeyValue);

        
/// <summary>
        
/// 查询数据库,检查是否存在指定ID的对象(用于整型主键)
        
/// </summary>
        
/// <param name="key">对象的ID值</param>
        
/// <returns>存在则返回指定的对象,否则返回Null</returns>

        T FindByID(int key);

        
/// <summary>
        
/// 查询数据库,检查是否存在指定ID的对象(用于字符型主键)
        
/// </summary>
        
/// <param name="key">对象的ID值</param>
        
/// <returns>存在则返回指定的对象,否则返回Null</returns>

        T FindByID(string key);

        
返回集合的接口
    }

细看上面代码,会发现由一个PagerInfo 的类,这个类是用来做分页参数传递作用的,根据这个参数,你可以知道具体返回那些关心的记录信息,这些记录又转换为强类型的List<T>集合。
再看看数据库访问基类的具体实现代码吧:
    /// <summary>
    
/// 数据访问层的基类
    
/// </summary>

    public abstract class BaseDAL<T> : IBaseDAL<T> where T : BaseEntity, new()
    
{
        
构造函数

        
通用操作方法