說在前
這個抽象類在我之前的文章中也有介紹過,而在“不忘本”系列中的抽象類,將會主要介紹它的概念及與介面的區別。
概念:
抽象類不同的普通類,它有自己的標示符abstract,在抽象類裡將可以出現抽象方法,它本身只能充當父類的角色,所以,它在真實的生產過程中,都是通過子類去實現的,即抽象類不能被例項化。前面說的父類有時我們經常叫它基類,比如你的WEB層的controller可能需要一個基類,用來儲存公用的屬性和方法,這時,抽象類是最好的選擇,在frameworks裡有很多這樣的例子,如System.Web.Mvc.Controller這就是一個抽象類,它由一組與控制器相關的方法及屬性元件。
在專案中的抽象類:
在我們實現專案中,我提倡每個層中都要有自己的基類,用來儲存公用的東西,如controller裡的BaseController,BLL層的BaseBll,data層裡的RepositoryBase等等,它們都是其它功能類的父類。
與介面的區別:
從概念上來說:
介面用來約束一組行為,實現介面的物件之前沒有本質聯絡,它是一種行為規範,或者是一種標示,通過介面我們可以實現多型!
抽象類一些相關聯的物件的一種抽象,將相關聯的物件的公用資訊進行抽象,放到一個類裡,而這個類往往叫它抽象類,用abstract進行標示。
從程式碼的角度來說:
介面是一組行為規範,看一個簡單倉儲介面
/// <summary> /// 基礎的資料操作規範 /// </summary> /// <typeparam name="TEntity"></typeparam> public interface IRepository<TEntity> where TEntity : class { /// <summary> /// 新增實體並提交到資料伺服器 /// </summary> /// <param name="item">Item to add to repository</param> void Insert(TEntity item); /// <summary> /// 移除實體並提交到資料伺服器 /// 如果表存在約束,需要先刪除子表資訊 /// </summary> /// <param name="item">Item to delete</param> void Delete(TEntity item); /// <summary> /// 修改實體並提交到資料伺服器 /// </summary> /// <param name="item"></param> void Update(TEntity item); /// <summary> /// 得到指定的實體集合(延時結果集) /// Get all elements of type {T} in repository /// </summary> /// <returns>List of selected elements</returns> IQueryable<TEntity> GetModel(); /// <summary> /// 根據主鍵得到實體 /// </summary> /// <param name="id"></param> /// <returns></returns> TEntity Find(params object[] id); }
它會叫每個具體的倉儲介面去實現它,如IUserRepository是使用者持久化的介面,同時它也可能被持久化基類去實現,如DbContextRepository,它是使用ef來完成持久化的基類,當然你可以使用MemoryContextRepository去實現IRepository這個介面,當然它的功能就是使用記憶體表來實現持久化的。
抽象類的程式碼展示:
/// <summary> /// 做為一個持久化機制的實現,它可能是ado.net,linq2sql,entityframeworks,nhibernate,redis,memoryStream,fileStream etc. /// 宗旨:我們不應該將資料持久化的方式暴露到業務(領域)層 /// 建立倉儲:為每個聚合根建立倉儲介面和實現,而不是為每個實體 /// 使用倉儲:應該根據使用場景去宣告為倉儲,而不是每次都是IExtensionRepository /// </summary> /// <typeparam name="TEntity"></typeparam> public class DemoContextRepository<TEntity> : IExtensionRepository<TEntity> where TEntity : class { #region IExtensionRepository<TEntity>成員 public void Insert(IEnumerable<TEntity> item) { throw new NotImplementedException(); } public void Update(IEnumerable<TEntity> item) { throw new NotImplementedException(); } public void Delete(IEnumerable<TEntity> item) { throw new NotImplementedException(); } public void Update<T>(System.Linq.Expressions.Expression<Action<T>> entity) where T : class { throw new NotImplementedException(); } public IQueryable<TEntity> GetModel(EntityFrameworks.Entity.Core.Specification.ISpecification<TEntity> specification) { throw new NotImplementedException(); } public IQueryable<TEntity> GetModel(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) { throw new NotImplementedException(); } public TEntity Find(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) { throw new NotImplementedException(); } public TEntity Find(EntityFrameworks.Entity.Core.Specification.ISpecification<TEntity> specification) { throw new NotImplementedException(); } public void BulkInsert(IEnumerable<TEntity> item, bool isRemoveIdentity) { throw new NotImplementedException(); } public void BulkInsert(IEnumerable<TEntity> item) { throw new NotImplementedException(); } public void BulkUpdate(IEnumerable<TEntity> item, params string[] fieldParams) { throw new NotImplementedException(); } public void BulkDelete(IEnumerable<TEntity> item) { throw new NotImplementedException(); } public event Action<EntityFrameworks.Entity.Core.SavedEventArgs> AfterSaved; public event Action<EntityFrameworks.Entity.Core.SavedEventArgs> BeforeSaved; #endregion #region IOrderableRepository成員 public IQueryable<TEntity> GetModel(Action<EntityFrameworks.Entity.Core.Orderable<TEntity>> orderBy) { throw new NotImplementedException(); } public IQueryable<TEntity> GetModel(Action<EntityFrameworks.Entity.Core.Orderable<TEntity>> orderBy, EntityFrameworks.Entity.Core.Specification.ISpecification<TEntity> specification) { throw new NotImplementedException(); } public IQueryable<TEntity> GetModel(Action<EntityFrameworks.Entity.Core.Orderable<TEntity>> orderBy, System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) { throw new NotImplementedException(); } #endregion #region IRepository<TEntity>成員 public void Insert(TEntity item) { throw new NotImplementedException(); } public void Delete(TEntity item) { throw new NotImplementedException(); } public void Update(TEntity item) { throw new NotImplementedException(); } public IQueryable<TEntity> GetModel() { throw new NotImplementedException(); } public TEntity Find(params object[] id) { throw new NotImplementedException(); } #endregion }
上面的抽象類只是一個DEMO,所以實現持久化的邏輯我並沒有實現,當然這並不是它的重點,重點在於你的具體倉儲如果繼承了它,將會以DemoContextRepository這種方式去持久化物件。