不忘本(ben)~抽象類
說在前
這個抽(chou)象類在我之(zhi)前的(de)(de)文(wen)章中也有介(jie)紹(shao)過,而在“不忘(wang)本”系列中的(de)(de)抽(chou)象類,將會主要介(jie)紹(shao)它的(de)(de)概念及(ji)與接口的(de)(de)區別。
概念:
抽(chou)象類(lei)不同的(de)(de)(de)普通(tong)類(lei),它(ta)(ta)有(you)自己的(de)(de)(de)標示符(fu)abstract,在抽(chou)象類(lei)里將(jiang)可以(yi)出現抽(chou)象方法,它(ta)(ta)本身只(zhi)能充當父類(lei)的(de)(de)(de)角色(se),所以(yi),它(ta)(ta)在真實(shi)的(de)(de)(de)生(sheng)產過程中,都是通(tong)過子類(lei)去實(shi)現的(de)(de)(de),即抽(chou)象類(lei)不能被實(shi)例化。前面(mian)說的(de)(de)(de)父類(lei)有(you)時(shi)我們(men)經常叫它(ta)(ta)基類(lei),比如你(ni)的(de)(de)(de)WEB層的(de)(de)(de)controller可能需要一(yi)(yi)個基類(lei),用來存儲公用的(de)(de)(de)屬(shu)性和方法,這(zhe)(zhe)時(shi),抽(chou)象類(lei)是最(zui)好的(de)(de)(de)選(xuan)擇,在frameworks里有(you)很多這(zhe)(zhe)樣的(de)(de)(de)例子,如System.Web.Mvc.Controller這(zhe)(zhe)就(jiu)是一(yi)(yi)個抽(chou)象類(lei),它(ta)(ta)由一(yi)(yi)組與控制器相關的(de)(de)(de)方法及(ji)屬(shu)性組件。
在項目中的抽象類:
在我(wo)們(men)實現項目中(zhong),我(wo)提倡每個(ge)層中(zhong)都要(yao)有自己的(de)(de)基類(lei)(lei),用來存儲公用的(de)(de)東西,如controller里(li)的(de)(de)BaseController,BLL層的(de)(de)BaseBll,data層里(li)的(de)(de)RepositoryBase等等,它們(men)都是(shi)其它功能類(lei)(lei)的(de)(de)父類(lei)(lei)。
與接口的區別:
從概念上來說:
接口(kou)(kou)(kou)用來約(yue)束一組行為,實現(xian)接口(kou)(kou)(kou)的對象(xiang)之前沒有(you)本質聯系,它是一種行為規(gui)范,或(huo)者是一種標示,通過接口(kou)(kou)(kou)我們可以實現(xian)多(duo)態!
抽象(xiang)類一(yi)些相(xiang)關(guan)聯(lian)的對象(xiang)的一(yi)種抽象(xiang),將相(xiang)關(guan)聯(lian)的對象(xiang)的公用信息進行抽象(xiang),放到一(yi)個(ge)類里,而這個(ge)類往往叫(jiao)它抽象(xiang)類,用abstract進行標(biao)示。
從代碼的角度來說:
接(jie)口是(shi)一組行為規范(fan),看一個簡單倉儲接(jie)口
/// <summary> /// 基(ji)礎的數據操作規范 /// </summary> /// <typeparam name="TEntity"></typeparam> public interface IRepository<TEntity> where TEntity : class { /// <summary> /// 添加實體并提交到數(shu)據服務器 /// </summary> /// <param name="item">Item to add to repository</param> void Insert(TEntity item); /// <summary> /// 移除實體并提交到數據服(fu)務器 /// 如果(guo)表(biao)(biao)存在(zai)約束,需要先刪(shan)除子表(biao)(biao)信息 /// </summary> /// <param name="item">Item to delete</param> void Delete(TEntity item); /// <summary> /// 修改實體并提交到數據服(fu)務器 /// </summary> /// <param name="item"></param> void Update(TEntity item); /// <summary> /// 得到指(zhi)定的實(shi)體集合(延時結果集) /// Get all elements of type {T} in repository /// </summary> /// <returns>List of selected elements</returns> IQueryable<TEntity> GetModel(); /// <summary> /// 根據主鍵得(de)到實(shi)體(ti) /// </summary> /// <param name="id"></param> /// <returns></returns> TEntity Find(params object[] id); }
它會叫每個(ge)具體的(de)倉(cang)儲(chu)接(jie)口(kou)去(qu)實(shi)(shi)現(xian)它,如IUserRepository是(shi)用戶持久(jiu)(jiu)化(hua)的(de)接(jie)口(kou),同(tong)時它也可(ke)能被(bei)持久(jiu)(jiu)化(hua)基(ji)類去(qu)實(shi)(shi)現(xian),如DbContextRepository,它是(shi)使用ef來完成持久(jiu)(jiu)化(hua)的(de)基(ji)類,當然你可(ke)以使用MemoryContextRepository去(qu)實(shi)(shi)現(xian)IRepository這個(ge)接(jie)口(kou),當然它的(de)功能就是(shi)使用內存表(biao)來實(shi)(shi)現(xian)持久(jiu)(jiu)化(hua)的(de)。
抽象類的代碼展示:
/// <summary> /// 做為一(yi)個持久化(hua)機制的(de)實現,它可(ke)能是ado.net,linq2sql,entityframeworks,nhibernate,redis,memoryStream,fileStream etc. /// 宗(zong)旨:我(wo)們不應該將(jiang)數據持久化(hua)的方式暴露到業務(領域(yu))層 /// 建立倉儲:為(wei)每個聚合(he)根建立倉儲接口(kou)和實(shi)(shi)現,而不是(shi)為(wei)每個實(shi)(shi)體(ti) /// 使用倉儲:應(ying)該根據使用場景去聲明為倉儲,而(er)不是每次都(dou)是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 }
上面的(de)(de)抽象(xiang)類只是一(yi)個DEMO,所(suo)以實現持(chi)久(jiu)化(hua)的(de)(de)邏(luo)輯我并(bing)沒有實現,當(dang)然這并(bing)不是它的(de)(de)重(zhong)點,重(zhong)點在于你(ni)的(de)(de)具體倉儲如果繼承了(le)它,將會以DemoContextRepository這種方式去持(chi)久(jiu)化(hua)對象(xiang)。