天天看點

.NET項目開發—淺談面向對象的縱橫向關系、多态入口,單元測試(項目小結)1】開篇介紹2】使用委托消除函數串聯調用3】多态入口(面向對象繼承體系是可以被擴充的)4】多态的受保護方法的單元測試

閱讀目錄:

1.開篇介紹

2.使用委托消除函數串聯調用

2.1.使用委托工廠轉換兩個獨立層面的對象

3.多态入口(面向對象繼承體系是可被擴充的)

4.多态的受保護方法的單元測試(Protected成員的單元測試)

一如既往,這篇文章是我最近在工作中總結出的一點小小的經驗,特此寫出來與大家分享,因為我覺得日常開發中這些點點滴滴很有用;

在一般的函數調用情況下,我們都習慣性的将參數傳入到某個被調用的方法,這可能就是我們考慮調用方法的慣用思維,但是現在的C#語言得到了很大的提升,我們可以很自然的使用委托來減少函數之間的參數依賴;有時候會經常看見一個函數的内部邏輯并沒有使用到傳入的某個參數,而傳入的真正目的是為了再傳入到本函數需要調用的另外一個函數中去;

圖1:

<a href="http://blog.51cto.com/attachment/201311/201944747.jpg"></a>

這個時候我們可以試着使用委托來封裝調用的方法,然後将委托執行個體傳入到第一層使用的函數中去,當然要厘清使用場景,不是所有的場景都合适;

圖2:

<a href="http://blog.51cto.com/attachment/201311/202008525.jpg"></a>

當然需要平衡好這裡的内聯變量ProductContent,如果可以的話盡量将委托放入到專門建立委托的委托工廠中去,這樣友善全局管理,甚至進一步抽象就可以将委托移除程式寫死到配置檔案;

一般情況下,我們在應用層會通過資料通路層的代碼擷取到資料源中的對應資料實體,然後将其進行DomainModel話,隻有這樣我們才能使用到面向對象的強大功能;這個時候我們隻需将建立DomainModel的委托工廠構造好,然後作為參數傳入到資料通路接口中去;由于應用層是全局協調層,它可以去完成多層之間的協調操作,是以對于應用層的設計可以盡量飽滿一點,而不是很簡單的一個靜态方法集合,這樣就會使得Application Layer很薄;

很多時候我們在設計一個架構的時候我們都會注意對象的繼承體系,但是我們基本上都沒有為這些内部對象留有對外的擴充入口;現假設你有一個架構内部的類XmlConvert,該類被XmlConvertSetting全局靜态類引用着,如果不能通過XmlConvertSetting對XmlConvert進行設定,就無法使用到XmlConvert的所有對外提供的擴充方法;

1

2

3

4

5

6

7

<code>public</code> <code>class</code> <code>XmlConvert</code>

<code>   </code><code>{</code>

<code>       </code><code>protected</code> <code>virtual</code> <code>string</code> <code>ConvertReplace(StringBuilder NodeString)</code>

<code>       </code><code>{</code>

<code>           </code><code>return</code> <code>NodeString.ToString().Replace(</code><code>"XXX"</code><code>, </code><code>"LLL"</code><code>);</code>

<code>       </code><code>}</code>

<code>   </code><code>}</code>

有一個很簡單的XmlConvert類,是架構内部使用的,現在它提供了一個Virtual方法ConvertReplace,我們想使用這個架構内部的類進行擴充;

<code>public</code> <code>class</code> <code>CustomerXmlConvert : XmlConvert</code>

<code>{</code>

<code>    </code><code>protected</code> <code>override</code> <code>string</code> <code>ConvertReplace(StringBuilder NodeString)</code>

<code>    </code><code>{</code>

<code>        </code><code>return</code> <code>base</code><code>.ConvertReplace(NodeString).Replace(</code><code>"JJJ"</code><code>, </code><code>"AAA"</code><code>);</code>

<code>    </code><code>}</code>

<code>}</code>

但是如果未能提供給我們一個多态入口,我們這個自定義的CustomerXmlConvert無法起作用;最近發現很多自定義的架構設計上就有這個問題,留有了擴充的類型和相應的方法,但是無法插入到架構内部去,是以特此分享一下;

受保護方法的單元測試一直都不太好解決,但是我們可以通過簡單的繼承方式來輕松的處理,就拿上面提到的XmlConvert類來舉例;

<code>    </code><code>protected</code> <code>virtual</code> <code>string</code> <code>ConvertReplace(StringBuilder NodeString)</code>

<code>        </code><code>return</code> <code>NodeString.ToString().Replace(</code><code>"XXX"</code><code>, </code><code>"LLL"</code><code>);</code>

如果我們想測試它,直接使用類型繼承就可以:

8

9

10

11

<code>[TestClass]</code>

<code>public</code> <code>class</code> <code>XmlConvertTests : XmlConvert</code>

<code>    </code><code>[TestMethod]</code>

<code>    </code><code>public</code> <code>void</code> <code>XmlConvert_ConvertReplace_Normal()</code>

<code>        </code><code>StringBuilder testData = </code><code>new</code> <code>StringBuilder(</code><code>"XXXJJJ"</code><code>);</code>

<code>        </code><code>string</code> <code>testResult = </code><code>this</code><code>.ConvertReplace(testData);</code>

<code>        </code><code>Assert.AreEqual(testResult, </code><code>"JJJ"</code><code>);</code>

這裡有一個很好的設計啟發就是将方法碎片化盡量保持有傳回值的操作,這樣很好的進行Assert;其實提到單元測試,冥冥之中總覺得它與面向對象有着一脈相承的感覺,甚至單元測試、重構、面向對象都會起到互補的作用;

内容不多,隻是簡單的項目小小的總結,希望對大家有用,謝謝;

 本文轉自 王清培 51CTO部落格,原文連結:http://blog.51cto.com/wangqingpei557/1329246,如需轉載請自行聯系原作者