天天看点

.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,如需转载请自行联系原作者