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);

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

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

  • 相关阅读:
    关于32位操作系统和64位操作系统对InstallShield打包的影响
    NEWS: Symantec宣布Wise Package Studio将终止
    InstallShield 2012新功能试用(2) 调用MsiGetProperty等MSI API发生变化
    Basic INFO 在命令行Build InstallShield安装包工程获得压缩安装包
    NEWS InstallShield 2012 Service Pack 1发布
    Basic INFO InstallShield Basic MSI工程中如何在SetupCompleteSuccess界面中启动Readme
    Basic INFO InstallShield的脚本编辑器中如何显示代码行号
    Basic INFO 关于在InstallShield制作的安装包界面中删除InstallShield文字的厂商回复
    Basic INFO InstallShield工程中如何让产品的快捷方式名称始终与产品名保持一致
    Basic INFO: 创建隐藏文件夹
  • 原文地址:https://www.cnblogs.com/AlexQY/p/2875376.html
Copyright © 2011-2022 走看看