zoukankan      html  css  js  c++  java
  • 关于泛型接口的探讨

    大家在用三层架构做开发的时候,是否有使用接口,使用接口的时候是否有类似这样的代码:

    public interface IT_logs
        {
            #region  成员方法
            /// <summary>
            /// 得到最大ID
            /// </summary>
            int GetMaxId();
            /// <summary>
            /// 是否存在该记录
            /// </summary>
            bool Exists(int Id);
            /// <summary>
            /// 增加一条数据
            /// </summary>
            int Add(Maticsoft.Model.T_logs model);
            /// <summary>
            /// 更新一条数据
            /// </summary>
            bool Update(Maticsoft.Model.T_logs model);
            /// <summary>
            /// 删除一条数据
            /// </summary>
            bool Delete(int Id);
            bool DeleteList(string Idlist );
            /// <summary>
            /// 得到一个对象实体
            /// </summary>
            Maticsoft.Model.T_logs GetModel(int Id);
            Maticsoft.Model.T_logs DataRowToModel(DataRow row);
            /// <summary>
            /// 获得数据列表
            /// </summary>
            DataSet GetList(string strWhere);
            /// <summary>
            /// 获得前几行数据
            /// </summary>
            DataSet GetList(int Top,string strWhere,string filedOrder);
            int GetRecordCount(string strWhere);
            DataSet GetListByPage(string strWhere, string orderby, int startIndex, int endIndex);
            /// <summary>
            /// 根据分页获得数据列表
            /// </summary>
            //DataSet GetList(int PageSize,int PageIndex,string strWhere);
            #endregion  成员方法
            #region  MethodEx
    
            #endregion  MethodEx
        } 

    然后每个每个表都有一个这样的接口代码,对比之后发现,这样的代码是不是很多重复呢?
    那么有什么好的办法可以减少这样的重复代码???

    我想到的是泛型,接口同样可以泛型,看下面这张图,IT_admin,IT_advs,IT_artClass......,它们内部代码几乎一模一样

    如果我们写这样的一个泛型接口,那么这一个接口就代替了上面所有的Idal接口,并且你再增加表,也不需要添加Idal的接口文件了,是不是很爽?

    public interface IOperate<T>
        {
            bool UpdateData(T entityData);//添加、编辑
            bool Delete(int Id);//根据ID号删除数据
            DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount);//返回数据表
            List<T> GetList(string sqlsStr);//返回LIST
            T GetDataById(int Id);//返回实体对象
        }

    代码很简单,我就不多做解释了,然后我们用每个DAL去实现这个接口,就可以,这样就不需要去为每个DAL单写一个接口了,要知道,每个DAL里的操作90%都是相同的,当然,我们也可以扩展一些其它方法出来。

    其实为每个表写DAL中,也是有功能可以抽象出来的,比如:删除,判断ID号是否存在,每个DAL所操作的表名,和表的主键,还有数据库操作对象,这些内容其实也可以抽象出来,所以我想到建立一个DALBASE的抽象类,提供一些虚方法,如果哪个DAL不一样,那就重写虚方法就可以了。所以有了下面这个类

    public abstract class DalBase
        {
            protected string TableName { set; get; }
            protected string PkField { set; get; }
    
            protected Database da = DatabaseFactory.CreateDatabase();
            /// <summary>
            /// 删除
            /// </summary>
            /// <param name="Id"></param>
            /// <returns></returns>
            public virtual bool Delete(int Id)
            {
                var sqlStr = "delete from {0} where {1}=@Id";
                sqlStr = string.Format(sqlStr, this.TableName, this.PkField);
                var command = da.GetSqlStringCommand(sqlStr);
                da.AddInParameter(command, "@Id", DbType.Int32, Id);
                return da.ExecuteNonQuery(command) > 0;
            }
           /// <summary>
           /// 判断是否存在
           /// </summary>
           /// <param name="Id"></param>
           /// <returns></returns>
            public virtual bool IsExists(int Id)
            {
                var sqlStr = "select count(*) from @TableName where @PkField=@Id";
                var command = da.GetSqlStringCommand(sqlStr);
                da.AddInParameter(command, "@TableName", DbType.String, this.TableName);
                da.AddInParameter(command, "@PkField", DbType.String, this.PkField);
                da.AddInParameter(command, "@Id", DbType.Int32, Id);
                var obj = da.ExecuteScalar(command);
                if (obj != null && !Convert.IsDBNull(obj))
                {
                    return int.Parse(obj.ToString()) > 0;
                }
                return false;
            }
           
        }

    那么DAL类的代码应该是怎么样?

    public class AdminDal : DalBase, IOperate<AdminEntity>
        {
    
            public AdminDal()
            {
                this.TableName = "T_Admin";
                this.PkField = "Id";
            }
            /// <summary>
            /// 添加,编辑
            /// </summary>
            /// <param name="entityData"></param>
            /// <returns></returns>
            public bool UpdateData(AdminEntity entityData)
            {
                var sqlStr = string.Empty;
                DbCommand command;
                if (entityData.Id == 0)//添加
                {
                    sqlStr = @"insert into {0}(UserName,UserPwd,Flag,PostTime) values(@UserName,@UserPwd,@Flag,@PostTime)";
                    sqlStr = string.Format(sqlStr, this.TableName);
                    command = da.GetSqlStringCommand(sqlStr);
                }
                else//编辑
                {
                    sqlStr = @"update {0} set UserPwd=@UserPwd,Flag=@Flag,PostTime=@PostTime where {1}=@Id";
                    sqlStr = string.Format(sqlStr, this.TableName, this.PkField);
                    command = da.GetSqlStringCommand(sqlStr);
                    da.AddInParameter(command, "@Id", DbType.Int32, entityData.Id);
                }
                da.AddInParameter(command, "@UserName", DbType.String, entityData.UserName);
                da.AddInParameter(command, "@UserPwd", DbType.String, entityData.UserPwd);
                da.AddInParameter(command, "@Flag", DbType.String, entityData.Flag);
                da.AddInParameter(command, "@PostTime", DbType.DateTime, entityData.PostTime);
                return da.ExecuteNonQuery(command) > 0;
            }
    
            public List<AdminEntity> GetList(string sqlStr)
            {
                var list = new List<AdminEntity>();
                var command = da.GetSqlStringCommand(sqlStr);
                var dt = da.ExecuteDataSet(command).Tables[0];
                if (dt != null && dt.Rows.Count > 0)
                {
                    foreach (DataRow dr in dt.Rows)
                    {
                        var entity = new AdminEntity()
                        {
                            Id = int.Parse(dr["Id"].ToString()),
                            UserName = dr["UserName"].ToString(),
                            UserPwd = dr["UserPwd"].ToString(),
                            Flag = dr["Flag"].ToString(),
                            PostTime = DateTime.Parse(dr["PostTime"].ToString())
                        };
                        list.Add(entity);
                    }
                }
                return list;
            }
            //分页查询,需要SQL2005 以上的版本支持
            /*private const string DefaultSqlStr = @"
            SELECT * FROM (
                SELECT row_number() OVER({0}) as ROW_NUMBER,* FROM 
                ( 
                    SELECT *  FROM T_admin
                    {1}
                ) as a
            ) as b WHERE ROW_NUMBER > {2} AND ROW_NUMBER <= {3}";
             */
            //分页查询
            private const string DefaultSqlStr = @"select top {0} * from {1} where {2} not in (select top {3} {4} from {5} where 1=1 {6} {7}) {8} {9} ";
            private const string DefaultSqlCount = @"select count(*)  FROM {0} where 1=1 {1}";
            public DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount)
            {
                var sql = String.Format(DefaultSqlCount, this.TableName, where);
                var obj = da.ExecuteScalar(CommandType.Text, sql);
                recordCount = 0;
                if (obj != null && !Convert.IsDBNull(obj))
                {
                    recordCount = int.Parse(obj.ToString());//记录条数
                }
                pageIndex = pageIndex > 0 ? pageIndex : 1;//最小为1
                if (string.IsNullOrEmpty(orderBy))
                {
                    orderBy = " order by " + this.PkField + " Desc";
                }
                sql = String.Format(DefaultSqlStr, pageSize, this.TableName, this.PkField, (pageIndex - 1) * pageSize, this.PkField, this.TableName, where, orderBy, where, orderBy);
                return da.ExecuteDataSet(CommandType.Text, sql).Tables[0];
            }
            public AdminEntity GetDataById(int Id)
            {
                var sqlStr = "select * from {0} where {1}=@Id";
                sqlStr = string.Format(sqlStr, this.TableName, this.PkField);
                var command = da.GetSqlStringCommand(sqlStr);
                da.AddInParameter(command, "@Id", DbType.Int32, Id);
                var dt = da.ExecuteDataSet(command).Tables[0];
                if (dt != null && dt.Rows.Count > 0)
                {
                    var dr = dt.Rows[0];
                    var entity = new AdminEntity()
    
                    {
                        Id = int.Parse(dr["Id"].ToString()),
                        UserName = dr["UserName"].ToString(),
                        UserPwd = dr["UserPwd"].ToString(),
                        Flag = dr["Flag"].ToString(),
                        PostTime = DateTime.Parse(dr["PostTime"].ToString())
                    };
                    return entity;
                }
                return null;
            }
    
    
        }

    DAL类继承了DalBase,并实现了泛型接口。。
    最后我们要完成Bll类:

    public class AdminBll
        {
            private static readonly IOperate<AdminEntity> iDal = new AdminDal();
            public static bool UpdateData(AdminEntity entity)
            {
                return iDal.UpdateData(entity);
            }
            public static bool Delete(int Id)
            {
                return iDal.Delete(Id);
            }
            public static List<AdminEntity> GetList(string sqlStr)
            {
                return iDal.GetList(sqlStr);
            }
            public static DataTable GetTable(string where, string orderBy, int pageIndex, int pageSize, out int recordCount)
            {
                return iDal.GetTable(where, orderBy, pageIndex, pageSize, out recordCount);
            }
            public static AdminEntity GetDataById(int id)
            {
                return iDal.GetDataById(id);
            }
    
        }


    那么,当我们需要调用方法的时候,代码是怎么样的?

    var adminEntity = new AdminEntity()
                {
                    UserName = "admin888",
                    UserPwd = "admin888",
                    Flag = "0",
                    PostTime = DateTime.Now
                };
                AdminBll.UpdateData(adminEntity);

    这样就实现了一个添加的操作。。。

    其实我自己并不确定这样去使用泛型接口是否合理,欢迎大家喷,但请告诉我原因,因为我自认自己是菜鸟,需要学习。。。

  • 相关阅读:
    Nested Lists比较经典的python代码
    Matching Character Ranges
    python 刷题记录
    SQL Access Advisor and SQL Tunning Advisor
    Reactor IO模型
    聊聊page cache与Kafka之间的事儿
    node.js cmd 输入npm-v无反应
    鼠标突然无反应,鼠标灯亮,鼠标灯不亮
    js图片转换为base64
    js实现倒计时60秒的简单代码
  • 原文地址:https://www.cnblogs.com/AlexQY/p/2875376.html
Copyright © 2011-2022 走看看