【设计模式】02-评判代码质量的标准?如何写出高质量代码?
想写出高质量的代码,我们要明确两个问题:
-
- 如何评价代码质量的高低怎么才能写出高质量代码?
- 从哪些维度评判?
- 做到什么程度才算高质量?
- 怎么才能写出高质量代码?
- 如何评价代码质量的高低怎么才能写出高质量代码?
一、如何评价代码质量的高低
在日常工作中,我们能经常能听到“这段代码写得好”、“这段代码写得烂”。这种描述过于笼统,也不符合我们程序员对于量化的追求。如果查查资料,我们会发现有一系列的形容词可以用来描述代码质量:
-
- 灵活性(flexibility)
- 可扩展性(extensibility)
- 可维护性(maintainability)
- 可读性(readability)
- 可理解性(understandability)
- 易修改性(changeability)
- 可复用(reusability)
- 可测试性(testability)
- 模块化(modularity)
- 高内聚低耦合(high cohesion loose coupling)
- 高效(high effciency)
- 高性能(high performance)
- 安全性(security)
- 兼容性(compatibility)
- 易用性(usability)
- 整洁(clean)
- 清晰(clarity)
- 简单(simple)
- 直接(straightforward)
- 少即是多(less code is more)
- 文档详尽(well-documented)
- 分层清晰(well-layered)
- 正确性(correctness、bug free)
- 健壮性(robustness)
- 鲁棒性(robustness)
- 可用性(reliability)
- 可伸缩性(scalability)
- 稳定性(stability)
- 优雅(elegant)
- 好(good)
- 坏(bad)
这一长串形容词列出来,实在让人头大——我们到底该用哪些词来描述代码质量?
实际上,这些词都是从不同维度出发来评价代码质量的,而且上面列出的评价维度并非完全独立,有些是相互影响甚至存在包含关系的。我们也很难用其中的某几个词汇来全面评价代码质量——代码质量是综合各种因素得到的结论。
经过以上解释,我们得出一个略微令人沮丧的事实——并没有一个客观的标准能量化代码质量的高低,评价代码质量是带有很强主观性的过程。因此,经验越深的工程师,给出的评价往往越准确。此外,如果没有其他人的指导,自己闷头写再多代码,也未必能在这方面获得明显提升。
二、最常用的评价标准
尽管上文讲到,评价代码质量是很主观的过程,但既然我们想搞清楚这个问题,还是要尽量给出相对客观的评判维度。对上文列出的形容词进行筛选,得到以下几个主要方面。
1. 可维护性(maintainability)
编码开发所说的“维护”无非就是修改 bug、修改老的代码、添加新的代码。
所谓“可维护性”,就是在不破坏原有代码设计、不引入新的 bug 的前提下,能够快速地修改或添加代码。
所谓“代码不易维护”,就是修改或添加代码有很大引入新 bug 的风险,且需要花费很长时间才能完成。
可维护性也是一个很难量化、偏向整体评价的标准,是由很多因素协同作用的结果。代码的可读性好、简洁、可扩展性好,就易于维护。代码分层清晰、模块化好、高内聚低耦合、遵从基于接口而非实现编程的设计原则,也就易于维护。此外,代码的可维护性还和项目代码量、业务复杂程度、所用技术复杂程度、文档是否全面、团队成员水平等因素有关。
通常来说,如果 bug 容易修复,能够轻松修改、添加功能,我们就主观地认为代码对我们来说易于维护。
2. 可读性(readability)
代码的可读性是评价代码质量最重要的指标之一,我们在编写代码时应时刻考虑代码是否易于阅读和理解。
代码的可读性会影响代码的可维护性。无论是修改 bug,还是修改、添加功能,都要先读懂代码。
评价代码的可读性,需要看以下几点:
-
- 代码是否符合编码规范;
- 是否见名知意;
- 注释是否详尽;
- 函数长短是否合适;
- 模块划分是否清晰;
- 是否符合高内聚低耦合。
此外,code review 是一个很好的测验代码可读性的手段。如果其他人可以轻松读懂我们写的代码,说明这段代码可读性较好。反之,说明代码可读性有待提高。
3. 可扩展性(extensibility)
可扩展性表示代码应对需求变化的能力,我们在不修改或者少量修改原有代码的情况下,通过扩展的方式添加新的功能代码。简而言之,代码预留了一些功能扩展点,可以将新功能代码直接插到扩展点上,不用为了添加一个功能大量改动代码。
代码是否易于扩展,在一定程度上也决定了代码是否易维护。
4. 灵活性(flexibility)
灵活性是比较抽象的概念。我们可以从以下几个场景出发来理解灵活性:
-
- 代码预留了扩展点,添加新功能时不用修改原有代码,在扩展点上添加新代码即可。
- 代码已经抽象出很多可以复用的模块、类等代码,添加新功能时可以拿来直接使用。
- 接口可以应对各种使用场景,满足各种不同的需求。
5. 简洁性(simplicity)
KISS 原则:Keep It Simple, Stupid。尽量用最简单的方法解决最复杂的问题。代码简单,逻辑清晰。
6. 可复用性(reusability)
尽量减少重复代码的编写,复用已有代码。DRY 原则:Don't Repeat Yourself.
7. 可测试性(testability)
可测试性是较少被提及,但非常重要的代码质量评价标准。如果代码可测试性差,比较难写单元测试,基本就可以认为代码设计有问题。
三、如何写出高质量代码
在以上七个维度的基础上,掌握更加细化、易于落地的编程方法论,譬如面向对象设计思想、设计原则、设计模式、编码规范、重构技巧等。后续的系列博客将详细分析。