第14讲:复杂的问题,一流的解决方案
2005.4.14 付仲恺
基础预习
熟悉.NET开发
有软件工程的相关经验
议题
代码插入
自定义对象在逻辑层间的传输
设计模式
小组构建工具
测试驱动开发
其它工具
代码插入
使用跟踪信息来调试并且配置代码
.NET提供了两种代码插入方式:
Debug
Trace
派生自System.Diagnostics命名空间
对测试版本使用Debug,而对所有版本使用Trace
遵循严格的格式设置并且只输出帮助了解程序流所需的最少内容
Trace和Debug类
方法:Write,WriteIf,WriteLine,WriteLineIf
当编译开关的Debug为真时,Debug类是活动的
当编译开关的Trace为真时,Trace类是活动的
Debug.WriteLineIf(ShowTrace,"ShowTrace");
使用TraceSwitch控制Trace类的输出
TraceSwitch类
继承自Microsoft System.Diagnostics
TraceSwitch是一个简单的条件类,它使得跟踪各个程序集、模块和类变得更加容易
TraceSwitch的目的是可以轻松地确定跟踪级别,以便代码能够即时生成适当的输出
提供了五种跟踪级别:
最高级别是Verbose,它意思是输出所有调试信息。
演示一
代码插入
WriteLineIf的第一个参数是条件,后面的参数是调试输出信息。下面是switch的配置文件,values的值是跟踪级别,这里为4表示输出所有的调试信息。
输出结果
TraceListener类
通过监听器实现代码跟踪的输出
我们每个输出的方式都是TraceListener对象数组中的对象。在Trace和Debug类在输出调试信息的时候系统会逐个枚举TraceListener数组中的每一个TraceListener类,并且让每一个类执行自己的输出处理。因此我们可以自己选择添加或者删除TraceListener对象来选择如何输出我们的调试信息。
系统自带了三种监听类:
System.Diagnostics.DefaultTraceListener
默认把调试信息输出到output debug窗口
System.Diagnostics.EventLogTraceListener
把调试信息输出到指定日志文件中
System.Diagnostics.TextWriterTraceListener
把调试信息输出到相应的流(文件流、控制流等)
通过继承System.Diagnostics.TraceListener抽象类,实现自定义输出类型
Trace.Listeners.Add(new ConsoleTraceListener());
Trace.WriteLine("Hello World!");
在App.config中也可以添加监听器
演示二
TraceListener输出调试信息到MSMQ
配置文件配置,下面是运行程序后,MSMQ中记录的调试信息
自定义对象在逻辑层间的传输
依赖于中间层的实现选择:
EnterpriseServices
Remoting
XML Web Service
从Web Service中,自定义对象使用XML序列化
XML序列化有着很大的限制:
只有对象中的公共字段和公共读/写属性被序列化为XML
私有属性,只读属性等不会被序列化
解决XML序列化限制
使用XmlIgnore属性来标记不可XML序列化的成员
这样在序列化的时候就会跳过这些标记了的属性避免异常的产生
创建可以被XML序列化的字符串类型的公共属性
在公共属性的get方法中
使用二进制序列化将不可XML序列化成员序列化到MemoryStream中
选择是否对数据流进行加密
产生Base64方式编码的可XML序列化的字符串
在公共属性的set方法中:
解码字符串到一个字节数组中
如果数据被加密,则进行解密处理
反二进制序列化字节数组成为原始的不可XML序列化的成员
演示三
在逻辑层传输数据操作结果对象
Role和Rule两个对象是不可序列化的对象,我们把它们放到HashTable类型的_Payload对象中,然后在序列化的时候对_Payload对象进行处理,让它变成可XML序列化的对象。
设计模式
设计模式描述了一组在设计中重复出现的问题的解决方案
设计模式描述了对象的设计以及相互之间的作用
设计模式分类:
创建型设计模式:描述怎样创建一个对象, 以及如何隐藏对象创建的细节,从而使得程序代码不依赖于具体的对象
结构型模式:描述类和对象之间如何进行有效的组织,形成良好的软件体系结构
行为型模式:描述类和对象之间如何交互以及如何分配职责
常用的设计模式
单件
抽象工厂
外观
观察者
模型-视图-控制器(MVC)
单件(Singleton)
创建型模式
确保一个类只有一个实例,并且为它提供一个全局的访问点
通过将构造函数私有化,防止单件类的重复实例化
使用静态方法来创建类的静态实例
抽象工厂模式
创建型模式
提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类
抽象工厂模式是一种比工厂模式抽象程度更高的模式
外观模式
结构型模式
提供了统一的接口以访问系统内部的复杂的子系统
包含两个角色:
外观角色与一个或者多个子系统角色的方法相联系,它将所有从客户端发来的请求委派到相应的子系统角色中去
子系统角色可以被客户端直接调用,或者被外观角色调用
子系统角色并不知道外观角色的存在,对于子系统角色而言,外观角色仅仅是另外一个客户端而已
观察者模式
行为型模式
在对象之间定义一对多的依赖关系,当一个对象的状态发生变更的时候,将通知并且更新所有与它相关的对象
包含主题角色和观察者角色
多个观察者对象同时监听某一个主体对象,主体对象在状态上发生变化时,会通知所有观察者对象进行更新操作
提供了订阅,通知和取消订阅三种操作
模型-视图-控制器模式
所谓MVC,指的是一种划分系统功能的方法,它将一个系统划分为三个部分:
模型:封装了数据源和所有对这些数据的操作
视图:将数据源的显示封装起来。一个模型可以有多个视图,而一个视图理论上也可以与不同的模型关联起来
控制器:封装的是外界作用于模型的操作,它在模型和视图之间起着桥梁的作用
这种模式实现模型和视图之间的松耦合,它们之间可以彼此不知道对方,而由控制器相互连接起来
演示四
设计模式
外观模式与单件模式
小组构建工具
NAnt:用于.NET自动化构建的工具
http://sourceforge.net/projects/nant
BuildIt:由Microsoft开发的自动化构建工具
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/tdlg_app.asp
演示五
NAnt自动化构建
demo1.build文件。NAnt默认只提供了命令行的操作方式
生成成功
demo2.build的内容多了一些xml代码,它的作用是在编译好项目之后自动运行。每一种不同的任务都是通过Target来配置的。
可以看到,build完成后程序自动运行了项目。
测试驱动开发
测试先行
单元测试数据的选择
正常数据
边界条件
坏数据
数据组合
NUnit:用户自动化单元测试的工具
http://sourceforge.net/projects/nunit
能够与NAnt整合在自动化构建后自动对组建执行单元测试
演示六
测试驱动开发
单元测试需要添加nunit引用,下面是测试代码
打开NUnit程序,点击Run可以运行单元测试
其它工具
FXCop是用于帮助检查.NET文件集问题的工具
关于这个工具的介绍:
http://msdn.microsoft.com/msdnmag/issues/04/06/Bugslayer/default.aspx
下载地址:
http://www.gotdotnet.com/team/fxcop/
CLR Profiler
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenethowto13.asp
DebugView
演示七
CLR Profiler
Class Graph
总结
Trace和Debug类在实现代码跟踪中发挥着重要作用
解决XML序列化在传递自定义对象时的局限性
设计模式能够帮助开发者构建更为灵活的代码
许多工具能够帮助开发者构建.NET应用程序
2010.10.24