將不確定變為確定~接口應該是什么
接口到底是什么,應該如(ru)何(he)去使(shi)用(yong)它呢?
書上說:“接口規定了(le)一組(zu)操(cao)作的規范,它將一些不相關的對象聯系在(zai)一起”,說是這樣說,但(dan)在(zai)實(shi)際當(dang)中我們應該(gai)如何去(qu)用(yong)(yong)接口,如何去(qu)用(yong)(yong)好接口呢?
事實上,我(wo)一直認(ren)為(wei),在面向對(dui)象中,接口就(jiu)(jiu)是(shi)大哥大,用好(hao)接口,理解好(hao)接口,你對(dui)面向對(dui)象的認(ren)識也將上升(sheng)一個新的臺階(jie),接口不可遺忘的功能就(jiu)(jiu)是(shi)它(ta)實現了(le)面向對(dui)象的多態(tai)性(xing),多態(tai),即一種對(dui)象,在接受指(zhi)定信息時(shi),實現指(zhi)定的對(dui)象實例,這其實就(jiu)(jiu)是(shi)我(wo)對(dui)多態(tai)的比較直觀(guan)的理解。
一個用戶操作(zuo)的接口可能(neng)是(shi)這樣被定(ding)義(yi):
1 /// <summary> 2 /// 用戶相關接口規范 3 /// </summary> 4 public interface IUserRepository : Data.IRepository<UserBases> 5 { 6 /// <summary> 7 /// 注冊(ce)流程 8 /// </summary> 9 /// <param name="entity"></param> 10 VMessage RegisterUser(UserBases entity); 11 12 void UpdateUser(UserBases entity); 13 /// <summary> 14 /// 登陸 15 /// </summary> 16 /// <param name="entity"></param> 17 /// <returns></returns> 18 VMessage Login(UserBases entity); 19 20 /// <summary> 21 /// 修改密碼 22 /// </summary> 23 /// <param name="entity"></param> 24 /// <returns></returns> 25 VMessage ChangePassword(UserBases entity); 26 }
但對于它的實現,我們(men)可(ke)以(yi)有多種,如可(ke)以(yi)是sqlserver的,而對于sqlserver來(lai)說,又可(ke)以(yi)是linq to sql的,ado.net的及ef的等(deng)等(deng)。
而對于一個(ge)用戶操作的(de)實現類,它將(jiang)被動的(de)去實現IUserRepository的(de)基(ji)接口(kou)IRepository,代碼如下:
1 /// <summary> 2 /// 用(yong)戶操作實現類 3 /// sqlserver-linq to sql實現 4 /// </summary> 5 public class UserRepository : Car_RentalRepositoryBase, IUserRepository 6 { 7 8 #region IUserRepository 成員 9 10 public VMessage RegisterUser(UserBases entity) 11 { 12 entity.Password = Utility.EncryptString(entity.Password, Utility.EncryptorType.MD5); 13 VMessage vm = new VMessage(); 14 try 15 { 16 base.InsertEntity(entity); 17 vm.IsComplete = true; 18 } 19 catch (Exception) 20 { 21 vm.IsComplete = false; 22 throw; 23 } 24 return vm; 25 26 } 27 28 public void UpdateUser(UserBases entity) 29 { 30 DB.SubmitChanges(); 31 } 32 33 public VMessage Login(UserBases entity) 34 { 35 VMessage vm = new VMessage(); 36 try 37 { 38 entity = this.GetModel().Where(i => i.Name == entity.Name && i.Password == Utility.EncryptString(entity.Password, Utility.EncryptorType.MD5)).FirstOrDefault(); 39 if (entity != null) 40 { 41 vm.IsComplete = true; 42 vm.Entity = entity; 43 } 44 else 45 vm.IsComplete = false; 46 } 47 catch (Exception) 48 { 49 vm.IsComplete = false; 50 throw; 51 } 52 return vm; 53 } 54 55 public VMessage ChangePassword(UserBases entity) 56 { 57 VMessage vm = new VMessage(); 58 try 59 { 60 vm = this.Login(entity); 61 62 if (vm.IsComplete) 63 { 64 entity = vm.Entity as UserBases; 65 entity.Password = Utility.EncryptString(entity.NewPassword, Utility.EncryptorType.MD5); 66 this.Update(entity); 67 vm.IsComplete = true; 68 } 69 else 70 vm.IsComplete = false; 71 } 72 catch (Exception) 73 { 74 vm.IsComplete = false; 75 throw; 76 } 77 return vm; 78 } 79 #endregion 80 81 #region IRepository<UserBases> 成員 82 83 public void Update(UserBases entity) 84 { 85 base.UpdateEntity(entity); 86 } 87 88 public void Update(IList<UserBases> list) 89 { 90 list.ToList().ForEach(entity => { this.Update(entity); }); 91 } 92 93 public void Insert(UserBases entity) 94 { 95 base.InsertEntity(entity); 96 } 97 98 public void Insert(IList<UserBases> list) 99 { 100 list.ToList().ForEach(entity => { this.Insert(entity); }); 101 } 102 103 public UserBases InsertGetIDENTITY(UserBases entity) 104 { 105 base.InsertEntity(entity); 106 return base.Find<UserBases>(entity.UserID); 107 } 108 109 public void Delete(UserBases entity) 110 { 111 base.DeleteEntity(entity); 112 } 113 114 public void Delete(IList<UserBases> list) 115 { 116 list.ToList().ForEach(entity => { this.Delete(entity); }); 117 } 118 119 public IQueryable<UserBases> GetModel() 120 { 121 return base.GetEntities<UserBases>().Select(item => new UserBases_Ext 122 { 123 CreateDate = item.CreateDate, 124 Email = item.Email, 125 Name = item.Name, 126 Status = item.Status, 127 UpdateDate = item.UpdateDate, 128 UserID = item.UserID, 129 Password = item.Password, 130 ConfirmCode = item.ConfirmCode, 131 ConfirmPassword = item.ConfirmPassword, 132 IDNumber = item.IDNumber, 133 IDType = item.IDType, 134 QQ = item.QQ, 135 Tel = item.Tel, 136 TelVerify = item.TelVerify, 137 }); 138 } 139 140 public UserBases Find(params object[] keyValues) 141 { 142 return base.Find<UserBases>(keyValues); 143 } 144 145 #endregion 146 }
而在(zai)業(ye)務(wu)層(ceng)去調用(yong)(yong)時,你(ni)可以使用(yong)(yong)IOC去建立實例(li),也可以在(zai)程序里寫(xie)死,但它為(wei)業(ye)務(wu)層(ceng)開放(fang)時,盡量(liang)是“構架方法”注入式的,以下是商品業(ye)務(wu)模塊的代(dai)碼片斷:
1 /// <summary> 2 /// 商品模(mo)塊(kuai)實現 3 /// </summary> 4 public class ProductService : ServiceBase, IProductService 5 { 6 IProductRepository iProductRepository = null; 7 /// <summary> 8 /// 默認構造方法 9 /// </summary> 10 public ProductService() 11 : this(new ProductRepository()) 12 { 13 14 } 15 /// <summary> 16 /// 構(gou)造方法,可以在建立(li)實例(li)時進行(xing)實現方式(shi)的選擇 17 /// </summary> 18 /// <param name="_iProductRepository"></param> 19 public ProductService(IProductRepository _iProductRepository) 20 { 21 iProductRepository = _iProductRepo
而(er)這樣,在上一層就(jiu)可以(yi)轉(zhuan)入接口的(de)一個實現就(jiu)可以(yi)了,這樣是否(fou)方(fang)便TDD呢,呵(he)呵(he)。