閱讀目錄:
- 1.開篇介紹
- 2.使用委託消除函式串聯呼叫
- 2.1.使用委託工廠轉換兩個獨立層面的物件
- 3.多型入口(物件導向繼承體系是可被擴充套件的)
- 4.多型的受保護方法的單元測試(Protected成員的單元測試)
1】開篇介紹
一如既往,這篇文章是我最近在工作中總結出的一點小小的經驗,特此寫出來與大家分享,因為我覺得日常開發中這些點點滴滴很有用;
2】使用委託消除函式串聯呼叫
在一般的函式呼叫情況下,我們都習慣性的將引數傳入到某個被呼叫的方法,這可能就是我們考慮呼叫方法的慣用思維,但是現在的C#語言得到了很大的提升,我們可以很自然的使用委託來減少函式之間的引數依賴;有時候會經常看見一個函式的內部邏輯並沒有使用到傳入的某個引數,而傳入的真正目的是為了再傳入到本函式需要呼叫的另外一個函式中去;
圖1:
這個時候我們可以試著使用委託來封裝呼叫的方法,然後將委託例項傳入到第一層使用的函式中去,當然要分清使用場景,不是所有的場景都合適;
圖2:
當然需要平衡好這裡的內聯變數ProductContent,如果可以的話儘量將委託放入到專門建立委託的委託工廠中去,這樣方便全域性管理,甚至進一步抽象就可以將委託移除程式硬編碼到配置檔案;
2.1】使用委託工廠轉換兩個獨立層面的物件
一般情況下,我們在應用層會通過資料訪問層的程式碼獲取到資料來源中的對應資料實體,然後將其進行DomainModel話,只有這樣我們才能使用到物件導向的強大功能;這個時候我們只需將建立DomainModel的委託工廠構造好,然後作為引數傳入到資料訪問介面中去;由於應用層是全域性協調層,它可以去完成多層之間的協調操作,所以對於應用層的設計可以儘量飽滿一點,而不是很簡單的一個靜態方法集合,這樣就會使得Application Layer很薄;
3】多型入口(物件導向繼承體系是可以被擴充套件的)
很多時候我們在設計一個框架的時候我們都會注意物件的繼承體系,但是我們基本上都沒有為這些內部物件留有對外的擴充套件入口;現假設你有一個框架內部的類XmlConvert,該類被XmlConvertSetting全域性靜態類引用著,如果不能通過XmlConvertSetting對XmlConvert進行設定,就無法使用到XmlConvert的所有對外提供的擴充套件方法;
1 public class XmlConvert 2 { 3 protected virtual string ConvertReplace(StringBuilder NodeString) 4 { 5 return NodeString.ToString().Replace("XXX", "LLL"); 6 } 7 }
有一個很簡單的XmlConvert類,是框架內部使用的,現在它提供了一個Virtual方法ConvertReplace,我們想使用這個框架內部的類進行擴充套件;
1 public class CustomerXmlConvert : XmlConvert 2 { 3 protected override string ConvertReplace(StringBuilder NodeString) 4 { 5 return base.ConvertReplace(NodeString).Replace("JJJ", "AAA"); 6 } 7 }
但是如果未能提供給我們一個多型入口,我們這個自定義的CustomerXmlConvert無法起作用;最近發現很多自定義的框架設計上就有這個問題,留有了擴充套件的型別和相應的方法,但是無法插入到框架內部去,所以特此分享一下;
4】多型的受保護方法的單元測試
受保護方法的單元測試一直都不太好解決,但是我們可以通過簡單的繼承方式來輕鬆的處理,就拿上面提到的XmlConvert類來舉例;
1 public class XmlConvert 2 { 3 protected virtual string ConvertReplace(StringBuilder NodeString) 4 { 5 return NodeString.ToString().Replace("XXX", "LLL"); 6 } 7 }
如果我們想測試它,直接使用型別繼承就可以:
1 [TestClass] 2 public class XmlConvertTests : XmlConvert 3 { 4 [TestMethod] 5 public void XmlConvert_ConvertReplace_Normal() 6 { 7 StringBuilder testData = new StringBuilder("XXXJJJ"); 8 string testResult = this.ConvertReplace(testData); 9 Assert.AreEqual(testResult, "JJJ"); 10 } 11 }
這裡有一個很好的設計啟發就是將方法碎片化儘量保持有返回值的操作,這樣很好的進行Assert;其實提到單元測試,冥冥之中總覺得它與物件導向有著一脈相承的感覺,甚至單元測試、重構、物件導向都會起到互補的作用;
內容不多,只是簡單的專案小小的總結,希望對大家有用,謝謝;