SOLID是面向对象的软件开发中的5条准则,也是开发人员可以提升自己代码质量的准则。那么如何衡量自己的代码是否符合SOLID准则呢?NDepend这款工具也许可以帮得上忙。本文将介绍一些NDepend的规则,这些规则可以帮助你来衡量你的代码的SOLID程度,并且提供一些可以让你的代码变得更好的建议。

原文连接:Use NDepend to Measure How SOLID Your Code Is - NDepend
作者 Carlos Schults。授权翻译,转载请保留原文链接。

https://www.ndepend.com/

NDepend和SRP

我们将首先处理SOLID中的“ S”:单一责任原则。这可能是SOLID原则中最容易被误解的东西,公平地说,这似乎是有原因的。关于什么构成责任存在一定程度的主观性。那么NDepend如何帮助解决这个难题呢?

避免类型过大

顾名思义,这条规则建议你保持较小的类型。保证你的类较小并不一定会使它们只承担一种责任,但是肯定会引导事情朝着这个方向发展。

听上去不错,但是“太大”有多大?根据规则的文档,超过200条逻辑代码行的类就属于过大了。

避免太多方法的类型

你可能会认为,鉴于前一个规则,这条规则有些多余,但事实并非如此。 除了大量方法外,类型还可能由于其他原因而过大,例如它可能有很多其他成员,或者可能只有一个巨大的方法。

但是,按照以前的规则,我们不得不问:“太多”是多少? 该规则的文档指出,如果每种类型有20个或更多的方法则被视为拥有太多方法,并补充说,诸如构造函数,属性和事件访问器之类的方法不被视为计数的一部分。

避免太多字段的类型

作为“避免太多...”系列的规则,这条规则涉及到了字段。该规则的文档说,它针对具有15个以上字段的类型,并且不考虑常量和只读静态字段以及枚举类型。

避免过大和过于复杂的方法

在这里,我们继续遵循鼓励简化设计的规则,但是现在我们关注的是方法级别。那么,方法的情况如何呢?我们是否只是要重复使用刚刚看到的相同规则,但是将“类型”替换为“方法”?

不,不是那么容易。在处理方法时,事情会变得有些复杂。首先让我们看看“避免方法过大和过于复杂”规则的文档说了些什么:

//<b> This rule matches methods where *ILNestingDepth* > 2
</b>//<b> and (*NbLinesOfCode* > 35
</b>//<b> or *CyclomaticComplexity* > 20
</b>//<b> or *ILCyclomaticComplexity* > 60)
</b>//<b> Such method is typically hard to understand and maintain.</b>

简而言之,该规则担心嵌套深度大于2且也符合其他几种条件之一的方法,例如代码行和循环复杂度。

避免使用参数过多的方法

该规则的名字已经表明了它的内容。我们真正需要做的是量化。多少是太多?

同样,我们必须求助于文档,这次文档中描述了参数过多指的是超过8个参数。调用这样的方法会十分痛苦。同样需要注意的是,一个有很多参数的方法是否也有可能本身的逻辑已经十分冗杂,处理多个事务了呢?有这样方法的类,应该使用单一职责原则来进行重构。

避免使用过多局部变量的方法

终于,最后一条用来帮助你使用单一职责原则检查自己代码的规则。就像之前介绍过的大多数规则一样,这条规则的名字也说明了它的内容。并且,这条规则只需要定义它所谓的“过多”是多少。而这个问题的答案,根据文档,是15个。

通过这一节的介绍,我们大致介绍了NDepend中可以帮助你使用SOLID原则中的单一职责原则的规则。

OCP 开闭原则

很多人认为开闭原则是所有原则中最难理解和应用的。所谓的开闭原则,指的是你的类型应该对拓展开放,但是对修改关闭。换句话说,对子类的增加一定不能导致父类的任何修改。NDEpend中的“基类不应该使用派生”规则通过指示基类永远不要提及其子类来帮助我们防止这种情况。

LSP 里氏替换原则

Robert Martin在一篇文章中对里氏替换原则下过如下定义:

派生类必须可以替代其基类。

当面对这样一条定义时,一些人会认为里氏替换原则多此一举,显得多余。那么这条原则的意义是什么呢?

好吧,这条原则的关键是人们一直在违反它!一种非常常见(也许是最常见)的情况是,让一个类实现一个或多个接口,然后抛出某种方式不适用的方法。

而NDepend恰好有一条规则可以警告你这种情况,这条规则被相当恰当地称为“实现抛出NotImplementedException的方法。”

你会发现,在使用TDD时,此异常最有用。这是一个非常常见的情况,如下所示:

  • 为一段代码编写测试时,你将调用一些不存在的方法。
  • 此时编译器会抱怨,而这是一件好事。
  • 然后你接受了Visual Studio的建议并生成了一个方法存根,因为你现在也不希望立即实现该方法。

如果你以后忘记实现该方法,则测试将失败,而这会提醒你。

这是NotImplementedException的可接受用法。如果你使用此(或其他)异常来避免实现某个接口,那么你将破坏LSP准则。

ISP 接口隔离原则

接口隔离原则指的是:

不应强迫客户端依赖于不使用的接口。

为了遵循此原理,你应该使接口尽可能的小和精细。换句话说,你应该避免接口太大,这是我们现在要讨论的NDepend规则的确切名称。

“太大”有多大?根据NDepend的文档:10。也就是说,该规则将提示具有10种以上方法的接口。

关于此规则的一件好事是,它也可以帮助你遵守之前提到过的里氏替换原则。如果使接口尽可能小,则可以降低客户端必须提供有意义的实现的可能性。一石二鸟!

DIP 依赖反转原则

所谓的依赖反转原则指的是:抽象接口不应该依赖于具体实现。而具体实现则应该依赖于抽象接口。

假设你有一个应用程序紧密耦合使用Microsoft SQL Server作为持久性解决方案。如果之后你需要更改使用另一个RDBMS,将​​会发生什么?这注定是一个痛苦的过渡过程。

反过来,如果你的应用程序的业务逻辑甚至没有意识到数据库的存在(通过采用适当的体系结构是可能的),则无需进行任何更改即可进行过渡。

为了帮助您解决此问题,NDepend制定了一个规则,即“高凝聚,低耦合”。 “高凝聚,低耦合”类似于“关注点分离”,简而言之,你希望你的软件具有很高的内聚性(“做一件事情并做好”),同时彼此之间的耦合性也很低。

这条NDepend规则通过鼓励你将包含抽象的命名空间与包含具体内容的命名空间(即所述抽象的实现)分开来帮助你实现此目的。

准备好编写更多SOLID代码了吗?

我们上面介绍的规则只是NDepend提供的规则中的一部分。它们足以使您的应用程序符合SOLID原则吗?当然不会。没有任何工具或技术可以保证一定改善你的代码。

但是,虽然规则本身并不能自动使你的代码完美无缺,但它们鼓励你编写较小,集中且不太复杂的类型,从而为你提供极大的帮助。

除此之外,通过不断阅读和研究SOLID原理,适当的架构以及通用的最佳实践和模式,你便可以正确地编写出色的应用程序。


阅读更多:

https://docs.microsoft.com/en-au/learn/?WT.mc_id=DT-MVP-5001664

使用NDepend衡量代码的SOLID程度的更多相关文章

  1. 代码整洁 vs 代码肮脏

    写出整洁的代码,是每个程序员的追求.<clean code>指出,要想写出好的代码,首先得知道什么是肮脏代码.什么是整洁代码:然后通过大量的刻意练习,才能真正写出整洁的代码. WTF/mi ...

  2. [代码质量] 代码质量管控 -- 复杂度检测 (JavaScript)

    转载自: https://juejin.im/post/59bb8b546fb9a00a4247532e 背景 代码的复杂度是评估一个项目的重要标准之一.较低的复杂度既能减少项目的维护成本,又能避免一 ...

  3. 高效完成R代码

    为什么R有时候运行慢? 参考https://www.cnblogs.com/qiaoyihang/p/7779144.html 一.为什么R程序有时候会很慢? 1.计算性能的三个限制条件 cpu ra ...

  4. 华为Java编程军规,每季度代码验收标准

    引言: 这个标准是衡量代码本身的缺陷,也是衡量一个研发人员本身的价值. 军规一:[避免在程序中使用魔鬼数字,必须用有意义的常量来标识.] 军规二:[明确方法的功能,一个方法仅完成一个功能.] 军规三: ...

  5. 深入理解javascript---如何编写高质量的代码?

    如何书写可维护的代码? 最小全局变量 JavaScript通过函数管理作用域.在函数内部声明的变量只在这个函数内部,函数外面不可用.另一方面,全局变量就是在任何函数外面声明的或是未声明直接简单使用的( ...

  6. 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点

    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 2011-12-28 23:00 by 汤姆大叔, 139489 阅读, 119 评论, 收藏, 编辑 才华横溢的 ...

  7. 高质量JavaScript代码书写基本要点

    翻译-高质量JavaScript代码书写基本要点 by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/ ...

  8. 【转】华为Java编程军规,每季度代码验收标准

    引言: 这个标准是衡量代码本身的缺陷,也是衡量一个研发人员本身的价值. 军规一:[避免在程序中使用魔鬼数字,必须用有意义的常量来标识.] 军规二:[明确方法的功能,一个方法仅完成一个功能.] 军规三: ...

  9. 阅读Google的C++代码规范有感

    李开复曾在微博上说过,Google的C++代码规范是全球最好的一份C++代码规范,没有之一.最近花了点时间看了下这份代码规范,收获确实很大,在编程过程中一些乱七八糟的坏习惯也该改一改了.最新的英文版见 ...

随机推荐

  1. Andrew Ng机器学习算法入门((七):特征选择和多项式回归

    特征选择 还是回归到房价的问题.在最开始的问题中,我们假设房价与房屋面积有关,那么最开始对房价预测的时候,回归方程可能如下所示: 其中frontage表示的房子的长,depth表示的是房子的宽. 但长 ...

  2. Kafka Rebalance机制和选举策略总结

    自建博客地址:https://www.bytelife.net,欢迎访问! 本文为博客同步发表文章,为了更好的阅读体验,建议您移步至我的博客 本文作者: Jeffrey 本文链接: https://w ...

  3. Log4j讲解

    讲解 通常,我们写代码的过程中,免不了要输出各种调试信息.在没有使用任何日志工具之前,都会使用 System.out.println 来做到. 这么做直观有效,但是有一系列的缺点:1. 不知道这句话是 ...

  4. 标签页切换title改变

    js实现如下 并将代码加入博客侧边栏就成了 <script> document.addEventListener("visibilitychange", functio ...

  5. Day015 Error和Exception

    Error和Exception 什么是异常 实际工作中,遇到的情况不可能是非常完美的.比如:你写的某个模块,用户输入不一定符合你的要求.你的程序要打开某个文件,这个文件可能不存在或者文件的格式不对,你 ...

  6. Beta——事后分析

    事后总结 NameNotFound 团队 项目 内容 北航-2020-软件工程(春季学期) 班级博客 要求 Beta事后分析 课程目标 通过团队合作完成一个软件项目的开发 会议截图 一.设想和目标 软 ...

  7. 关于Java的 long,float 类型

    发现了这么一个坑: 1.2f+3.4f=4.60000014305114751.2d+3.4d=4.6

  8. 在 Linux 中,最直观、最可见的部分就是 文件系统(file system)

    在 Linux 中,最直观.最可见的部分就是 文件系统(file system).下面我们就来一起探讨一下关于 Linux 中国的文件系统,系统调用以及文件系统实现背后的原理和思想.这些思想中有一些来 ...

  9. Zabbix 架构

    Zabbix 架构 1.Zabbix Server Zabblx server是agent程序报告系统可用性.系统完整性和统计数据的核心组件,是所有配置信息.统计信息和操作数据的核心存储器. 2.Za ...

  10. Maven 阿里云镜像配置

    1. 为什么要配置 Maven 阿里云镜像 安装 Maven 后默认是从国外 Maven 中央仓库下载内容,而下载速度简直可以用龟速来形容,不仅慢而且还经常出错,简直让人抓狂. 这时国内大厂阿里巴巴, ...