第一回 要想知道为什么抽象出基类,应该先对基类有一个比较明确的认识
基类,即基础类型,也称为父类,祖宗类等,它一般会以抽象类(abstract class)的形式体现出来,它会包括一些具有共性的,一般性的信息(属性和方法等),它在描述一类对象时,经常会被抽象出来,如一个小猫,一只小狗,很容易会让你抽象出一个animal来,这是正常的,是符合面向对象人生观的,呵呵。
而在实际项目开发中,这种例子也不少,可以说到处都可以看到基类的身影,有人说,请不要使用继承,因为它为使你的程序很糟糕,依赖太多不好,但我要说的是,如果你的程序是一个关系复杂,面向对象的,那你的程序在某些地方必须要去继承(抽象出基类),有时,我们会说,那什么时候去使用基类,我们应该如何去衡量呢?事实上这种衡量是没有意义的,是应试的,就像我国的教育,我是很不喜欢,永远都是应付考试,对于基类这东西,你需要它时,就使用它,不要管什么原则,当你需要解耦时,就使用对象的组合,还有,如果对基类还是有所偏见,那可以去看看微软的System.Collections和System.Web.Mvc下的实现,看看人家是如何设计的。
以下是一个完整的,简单的数据操作基类,它将子类公用的属性数据库上下文(DataContext)抽象出来,将增删改查的Curd操作也抽象出来,结果,这个基类就变成了这样:
1 /// <summary> 2 /// 标准数据操作基类 3 /// </summary> 4 public abstract class DataBase : IRepository 5 { 6 /// <summary> 7 /// 数据访问对象(只对子类可见) 8 /// </summary> 9 protected DataContext DB; 10 11 #region Constructors 12 public DataBase() 13 : this(new LINQ.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["XXB"].ToString())) 14 { } 15 public DataBase(DataContext db) 16 : this(() => { return db; }) 17 { } 18 public DataBase(Func<DataContext> func) 19 { 20 this.DB = func(); 21 } 22 #endregion 23 24 #region DBContext SubmitChanges 25 /// <summary> 26 /// XXB默认提交【重写时候可能需要写入自定义的类似约束的逻辑】 27 /// </summary> 28 protected virtual void SubmitChanges() 29 { 30 ChangeSet cSet = DB.GetChangeSet(); 31 if (cSet.Inserts.Count > 0 32 || cSet.Updates.Count > 0 33 || cSet.Deletes.Count > 0) 34 { 35 try 36 { 37 DB.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict); 38 } 39 catch (System.Data.Linq.ChangeConflictException) 40 { 41 foreach (System.Data.Linq.ObjectChangeConflict occ in DB.ChangeConflicts) 42 { 43 occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues); 44 occ.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues); 45 occ.Resolve(System.Data.Linq.RefreshMode.KeepChanges); 46 } 47 DB.SubmitChanges(); 48 } 49 } 50 } 51 52 #endregion 53 54 #region IRepository 成员 55 56 public virtual void Update<TEntity>(TEntity entity) where TEntity : class 57 { 58 this.SubmitChanges(); 59 60 } 61 62 public virtual void Update<TEntity>(IEnumerable<TEntity> list) where TEntity : class 63 { 64 list.ToList().ForEach(entity => 65 { 66 this.Update<TEntity>(entity); 67 }); 68 } 69 70 public virtual void Insert<TEntity>(TEntity entity) where TEntity : class 71 { 72 DB.GetTable<TEntity>().InsertOnSubmit(entity); 73 this.SubmitChanges(); 74 } 75 76 public virtual void Insert<TEntity>(IEnumerable<TEntity> list) where TEntity : class 77 { 78 DB.GetTable<TEntity>().InsertAllOnSubmit<TEntity>(list); 79 this.SubmitChanges(); 80 } 81 82 public virtual TEntity InsertGetIDENTITY<TEntity>(TEntity entity) where TEntity : class 83 { 84 this.Insert<TEntity>(entity); 85 return GetModel<TEntity>(i => i == entity).FirstOrDefault(); 86 } 87 88 public virtual void Delete<TEntity>(TEntity entity) where TEntity : class 89 { 90 DB.GetTable<TEntity>().DeleteOnSubmit(entity); 91 this.SubmitChanges(); 92 } 93 94 public virtual void Delete<TEntity>(IEnumerable<TEntity> list) where TEntity : class 95 { 96 DB.GetTable<TEntity>().DeleteAllOnSubmit<TEntity>(list); 97 this.SubmitChanges(); 98 } 99 100 public virtual IQueryable<TEntity> GetModel<TEntity>() where TEntity : class 101 { 102 return this.DB.GetTable<TEntity>(); 103 } 104 105 public virtual IQueryable<TEntity> GetModel<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity : class 106 { 107 return GetModel<TEntity>().Where(predicate); 108 } 109 110 public virtual TEntity Find<TEntity>(params object[] keyValues) where TEntity : class 111 { 112 var mapping = DB.Mapping.GetTable(typeof(TEntity)); 113 var keys = mapping.RowType.IdentityMembers.Select((m, i) => m.Name + " = @" + i).ToArray(); 114 TEntity entityTEntity = DB.GetTable<TEntity>().Where(String.Join(" && ", keys), keyValues).FirstOrDefault(); 115 if (entityTEntity != null) 116 DB.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, entityTEntity); 117 return entityTEntity; 118 } 119 120 #endregion 121 }
对于一个数据操作具体类来说,直接继承它就可以了,然后再去实现自己的业务逻辑,很清晰。