Patrick Smacchia是Visual C#的MVP,拥有超过15年的软件开发经验。他是《Practical .NET 2 and C# 2》一书的作者,该书通过真实的项目经验来阐释.NET平台。他的专业为数学与计算机科学,毕业后,他在多个领域从事过软件开发,包括在Société Générale开发股票交易系统,在Amadeus开发航空售票预订系统,以及在Alcatel开发卫星基站。目前他是NDepend工具的首席程序员。
Rob Bazinet (RB): NDepend是什么?
Patrick Smacchia (PS): NDepend是为.NET开发人员以及架构师开发的工具。代码库是那么的错综复杂,而NDepend工具则能够帮助人们从源代码中获取相关的信息。例如,NDepend能够判断你的代码库是否正确分层;获知从最近版本发布后所做的修改;或者评估某些关键任务的代码质量,如果这些事情通过传统工具来完成,可能会耗费数个小时甚至数天的时间。
RB: 是什么使你产生开发NDepend的念头?
PS: 5年前,我为一个巨大而又混乱的代码库提供咨询。而在同时,我正在阅读一本优秀的书籍,Robert C Martin所著的《敏捷软件开发——原则,模式与实践》 。本书描述了一些非常酷的评估代码库组件构成的度量标准。
正是在那个时候,我从C++转向了.NET。我所偏爱的其中一个特性是System.Reflection,它比C++的RTTI更加的引人注目。顺理成章的,我开始基于反射开发了一个小巧的工具,它能够针对这个巨大而又混乱的代码库去验证Martin所说的度量。然后,我将该工具发布为开源软件(OSS),由于它的功能能够满足许多需求,因而越来越受到人们的欢迎。基于此,我认识到如果该工具能够支持某些可视化以及查询的功能,那么对于我们处理代码复杂性而言,其效率就能再上一个台阶。
RB: NDepend对于我的编码工作以及/或者开发生命周期能够提供怎样的帮助呢?
PS: NDepend对多种任务都提供了很大的帮助,包括重构、代码评审、代码质量检查与增强、设计缺陷检查、代码侦测、代码浏览以及构建过程原则的实施。
NDepend对于代码重构非常有用,因为它能够展现组件、命名空间、类……之间的依赖关系,呈现的方式是一个依赖关系矩阵图以及一些由“框框和箭头”组成的图形。
NDepend支持超过60条编码准则,用于评估代码质量:
NDepend分析过程可以被集成到MSBuild或者NAnt构建过程中。每次执行分析之后都会给出一个关于构建过程健康度的报告。
通过使用代码查询语言(Code Query Language,CQL,一种能够提供代码结构查询的语言),开发人员能够对他们的代码库提出各种问题:
- 哪些类实现了IDisposable接口?
Select TYPES Where IsClass AND Implements "System.IDisposable" - 哪些公共方法能够被声明为private?
Select METHODS Where IsPublic AND CouldBePrivate - 哪些方法分配了特定的字段?
Select METHODS Where IsDirectlyWriting "MyNamespace.MyClass.m_Field" - 哪些复杂的方法没有足够的注释?
Select METHODS Where CyclomaticComplexity > 15 AND PercentageComment < 20
CQL语言还能够用来定义某些原则对每次构建进行检查。如果与原则冲突,用户就能够从报告中知晓。NDepend提供了50多条预先定义的原则,同时还允许用户自定义符合系统要求的原则,例如:
- 静态字段不能被命名为m_XXX(自定义的命名规范):
WARN IF Count > 0 IN Select FIELDS Where NameLike "^m_" AND IsStatic - 我不想让我的用户界面层直接依赖于DataBase层:
WARN IF Count > 0 IN Select NAMESPACES Where IsDirectlyUsing "DataLayer" AND NameIs "UILayer" - MyAssembly和MyAssembly2的方法不能超过30行代码:
WARN IF Count > 0 IN Select METHODS OUT OF ASSEMBLIES "MyAssembly1", "MyAssembly2" Where NbLinesOfCode > 30
NDepend可以比较代码库的两个版本。当我们即将发布一个新版本,以及需要进行冒烟测试,和对修改内容进行代码评审时,这一功能特性就格外的行之有效。此处,同样借助了CQL语言以探测版本之间的区别。例如,显示两个版本中被修改过的方法,需要编写:
- Select METHODS Where CodeWasChanged
最后,NDepend可以作为Visual Studio 2005以及2008的插件,也可以作为Reflector的插件,通过这些工具访问NDepend提供的功能特性。
RB: 若要使用NDepend,应该怎么入门?推荐的学习途径是什么?
PS:首先,需要下载NDepend,然后分析你的代码库。这些操作可以无缝地被执行,因为VisualNDepend的UI与Visual Studio的界面完全相同,甚至于界面效果更好。
一旦分析执行完毕,VisualNDepend的UI就会通过几个面板来显示分析结果。此时,如果用户希望浏览依赖关系或软件度量,或者通过CQL 语言查询代码库,以及比较分析结果等……都需要对此进行选择。无论内容的多少,每个功能特性都会提供一个专门的面板。同时还内嵌了一个“帮助”节,它包含了对 NDepend的入门介绍。一些视频广播还具有链接。它们为用户演示了如何执行每个特定的任务。最后,我们的网站还提供了一些高级文档,例如完整的CQL 规格说明书。
一旦用户掌握了每个功能特性,就能够统一地使用它们完成对代码库的评审与修正。
RB: NDepend能够工作在.NET Framework 3.5下吗?3.0呢?
PS: 可以,新的NDepend 2.6版本的Visual Studio插件可以工作在Visual Studio 2008下。而且,NDepend也能够分析.NET 3.5和3.0的程序集。
RB: NDepend是针对.NET语言的产品;你是否有计划开发针对其他平台的产品?是否有计划增加对动态代码库的分析?
PS: 是的。NDepend采用C#进行编码,但是在我们的代码中只有5%是专门针对于.NET代码分析的。这意味着95%的代码与要分析代码的平台是抽象隔离的。正是基于这种背景,目前就有一家公司octo technology 正在开发能够分析Java代码的NDepend版本。octo technology是一家法国的咨询公司,专注于软件与信息系统的架构设计,它汇聚了大量的Java和.NET专家。Octo的.NET咨询师喜欢使用 NDepend,而Java咨询师也希望能够获得同样的工具。我们决定对此进行合作。
XDepend项目(NDepend的Java版本)的beta版会在2008的第1个季度推出。
RB: 对于初学者而言,使用NDepend进行代码分析看起来非常复杂;你对此有什么好的建议或者指导吗?
PS: 在VisualNDepend的UI中内嵌了一个帮助节,包含了一些入门级介绍以及具有链接的视频广播。在www.ndepend.com/GettingStarted.aspx中可以获得一些大约3分钟长度的视频广播,内容是对NDepend的入门讲解。还有一些视频广播则介绍了在主页上推荐的主要用例场景。若要进一步学习,我们还提供了一些文档,例如完整的 CQL规格说明,对所有度量的描述文档,Scott Hanselman、Stuart Celarier和Patrick Caulwell共同发表的总结文档的PDF:NDepend metric placemats ,同时,在我们网站的documentation部分还提供了更多的内容。此外,我还会定期地更新博客(http://codebetter.com/blogs/patricksmacchia/default.aspx),并在那里阐述了NDepend的高级用法。
RB: 你们是否为软件团队提供培训,使得他们能够快速上手,并熟练地进行运用?
PS: 有时候我们会走访一些订阅了企业许可证以及希望获得特殊培训的客户。即使培训并非我们的主要工作,我们也要持续开展。与用户的直接联系会为我们提供更多的信息。功能特性的完善与用户的反馈是分不开的。
RB: 你认为NDepend最强或者说最好的功能特性是什么?而原因又在于什么?
PS: 这个问题很难回答,事实上,我们大量地使用了NDepend来规范NDepend的编码。我每天都在亲自使用度量去浏览依赖关系,确保体系架构保持清晰。我们拥有超过400条CQL原则,这些原则能够帮助我们持续不变地关注代码质量。我也为NDepend的比较特性所深深地吸引。我通常会使用它去评审发生改变的代码。我相信变化往往就是噩梦的开始。
所谓“一份耕耘,一份收获”,这种方式能够极大地改善我们的开发过程,使得我们能够以一种持续的节奏发布新的版本。更多的内容可以在我们的 发布笔记中找到。
RB: 今天,我们非常感谢Patrick牺牲宝贵的时间,指导我们了解了关于NDepend的知识。
有关NDepend的更多内容可以在NDepend的网站上找到。读者可以通过Patrick的博客了解更多Patrick的信息。