OverRainbow

Coding Principles of software development

☕️ 1 min read

你可以从本文了解到

本文是对《软件设计的 201 个原则》的第5章——软件开发的编码原则的学习

编码是包含以下行为的集合:

  • 将设计阶段确定的算法转换为用计算机语言编写的程序。

  • 将程序(通常是自动化的)转换为可被计算机直接执行的语言。

编码的主要输出结果就是一组形成文件的程序清单。

087 避免使用特殊技巧

底线:避免编写使用特殊技巧的代码,以向世界展示你有多聪明!

088 避免使用全局变量

“全局”意味着,任何人都可能错误的修改它的值。

可以将重要数据封装在对应模块中(原则 65),这样任何人都必须通过指定方式来访问或者修改它。可以显式传递参数给需要特定数据的程序。如果发现参数过多,那么可能你的设计需要改造。

089 编写可自上而下阅读的程序

要编写有助于读者理解的程序。

  • 顶部要包含详细的对外说明,用以明确定义程序的目的与用途。

  • 顶部要说明外部可访问的方式、局部变量和算法。

  • 使用被称为“结构化”的编程结构,这从本质上更易于遵循。

090 避免副作用

程序的副作用,是指程序的某些操作不是其主要目的,并且这些操作对程序外部可见(或其结果能被外部感知)。

副作用是软件中许多细微错误的来源。即,这些错误是潜伏最深的,一旦它们的症状表现出来是最难排查的。

091 使用有意义的命名

092 程序首先是写给人看的

现在最有价值的资源是人力:开发软件的人力,维护软件的人力和提高软件能力的人力。

如果你需要执行效率,这没问题,但要提升程序的可读性,以免在提升执行效率的过程中浪费人力。

093 使用最优的数据结构

如果你选择了正确的数据结构,算法(以及代码)将变得易于编写、阅读以及维护。

当你准备编写程序时,应该将算法和数据结构一起考虑。

在选择最佳组合之前,请尝试两个或三个或更多不同的组合。

应确保将数据结构封装在一个组件内(原则65),这样当发现更好的数据结构时,可以轻松地修改。

094 先确保正确,再提升性能

提升正常运行程序的性能,比“让高性能程序正常运行”容易很多。

当你进行初始编码时,不要担心优化问题。

在这种情况下,在任何时候一个组件要是能够按时(或者提前)完成并且可靠运行,应值得庆祝。

095 在写完代码之前写注释

我们写代码注释是为了让软件更易于调试、测试以及维护。

在写代码的同时写注释(或者提前写注释,参见原则 96),这会让你更容易调试软件。

当你调试软件时,无疑会发现一些错误。

如果从算法到代码的转换过程存在错误,那么你只需要修改代码,而不需要修改注释。

如果算法存在错误,那么你对注释和代码都需要修改。

但如果不写代码注释,你怎么能发现算法的错误呢?

096 先写文档后写代码

在为一个组件完成详细设计(即,将它的外部接口和算法写为文档)之后,在代码中编写行间注释。

这些注释大部分与前面完成的接口与算法的文档没什么不同。

之后将每行注释转化为与之对应的代码片段。(注意:如果最后发现每条注释只对应一行代码,你很可能对算法描述的过于细致了。)

你会发现调试过程变得顺畅许多。

097 手动运行每个组件

手工执行一些简单的测试用例,一个软件组件或许会花 30 分钟时间。

如果不这么做?现在节省30分钟,直接去做单元测试、集成测试和系统测试。

一旦系统挂了,将花费3–4人天的成本去定位失败的原因。

总之,30分钟比3–4人天加上6×30分钟的成本要少。

098 代码审查

软件的详细设计评审和代码审查,由 Michael Fagan 首次提出,论文标题为“用设计和代码审查减少程序中的错误”("Design and Code Inspections to Reduce Errors in Program Development",IBM Systems Journal, 15, 3 (July 1976), pp. 182–211)。

由此发现的错误,能占到所有被发现的软件错误的82%。

数据显示,你甚至可以减少 50% 至 90% 的测试时间。

099 你可以使用非结构化的语言

非结构化的代码打破了 Edsger Dijkstra 的建议,其要求对控制结构限制在 IF-THEN-ELSE, DO-WHILE, DO-UNTIL 和 CASE 几类。

注意,使用一种没有这些控制结构的语言(如,汇编语言),也可以写出结构化的代码。可以在代码中增加结构化控制的注释,并限制 GOTO 只能用来实现这些控制结构。

GOTO 语句会被使用到,但它们将实现更好的控制结构,并且将促进而不是妨碍可读性、可维护性和可证明性。

100 结构化的代码,未必是好的代码

但需要注意的是,并非所有的“结构化”程序都是好的。

对高质量的程序,结构几乎是必要条件,但远不是充分条件。

101 不要嵌套太深

嵌套超过三层会严重降低可理解性。

人类的头脑在变得混乱之前只能记住一定数量的逻辑。

102 使用合适的语言

103 编程语言不是借口

事实上,如果你是一个好的程序员,对任何一种编程语言你都应该是个好程序员(原则104);尽管不太理想的编程语言可能会让你的工作困难一些。

104 编程语言的知识没那么重要

不管使用哪种语言,优秀的程序员都是优秀的。不管使用哪种语言,糟糕的程序员仍然是糟糕的。不可能有一个人是"优秀的C程序员",同时是"糟糕的Ada程序员"。如果他确实在Ada语言上表现的很糟糕,那大概率也不会在C语言上表现很好!除此之外,一个真正优秀的程序员应该可以很容易的学会一种新语言。这是因为一个真正优秀的程序员理解和赞赏高质量编程的概念,而不只是某些编程语言的语法和语义特性。

所以,为一个项目选择语言的首要驱动力应该是什么语言更合适(原则102),而不是程序员都在抱怨“我们只知道C语言”。如果由于项目选择了其他语言而导致一些人退出,这个项目很可能会更好!

105 格式化你的代码

使用标准的缩进规则,可大大提高程序的可读性。选择遵循哪种规则无关紧要,但一旦选择了,就要维持一致。

106 不要太早编码

编写软件和盖房子类似。这两者都需要很多准备工作。没有坚固稳定的混凝土地基,盖房子不会成功。没有坚固稳定的需求和设计作为基础,编码也不会成功。想一想当地基已经浇筑完成之后,对房子做修改有多么困难!

不要因为管理层想看到“进展”,就被迫过早编写代码。在设立基线前,要确认需求和设计是正确且合适的,在对最终产品编码前更要确认。附带说一下,不要从这个原则推断出原型试验的方法有问题(原则5,10,11,12,13)。在需求基线完成很早之前,试验性编码没有错。只是不要认为这是最终的产品。针对本条原则,Manny Lehman 提出了一个相反的观点:不要太晚编码!