閱讀目錄:
- 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;其實提到單元測試,冥冥之中總覺得它與面向對象有着一脈相承的感覺,甚至單元測試、重構、面向對象都會起到互補的作用;
內容不多,只是簡單的項目小小的總結,希望對大家有用,謝謝;