软件开发的53条黄金法则:从质量到效率的实践指南 | 开发经验

软件开发的53条黄金法则:从质量到效率的实践指南 #

引言 #

在软件开发领域,有一些经过时间检验的核心原则和最佳实践。本文将通过51条实用建议,系统性地探讨如何提升代码质量、优化开发流程、提高团队效率。

最近在读《软件开发的 201 个原则》,书内容不多,但是每一页都看的很仔细,好像往往这种言简意赅的书更让人有静下心来仔细阅读的欲望。在我看来,读书的作用本来就不是解答所有的困惑,而是激发人更加深入地学习的动力。

如果看这本书的时候,你会主动搜索文献或者资料,去了解更多的信息,那说明这本书就已经帮助了你。话不多说,抛砖引玉,本文和大家分享下我的"读后感"。

01. 质量第一 #

编程一定要把质量放在首位,没有可商量的余地。当你被要求要为质量做妥协时,要直接说不。质量必须可量化。

02. 质量与效率的权衡 #

对质量要求越高,开发效率就越低。越是强调提高开发效率,最终的质量就越低,bug 的密度就会增加。

03. 提高软件质量的方法 #

  • 让客户参与
  • 在全面开发之前验证需求
  • 保持设计简单
  • code review
  • 雇佣最优秀的人

04. 尽早交付产品 #

在需求阶段,无论你多努力了解客户需求,都不如给他们一个产品,让他们使用后确定自己的真实需求。可以在开发过程的早期构建一个快速且粗糙的原型,交给用户,收集反馈,然后确定真正的需求。最终产品也就更有可能让客户满意。

05. 与客户沟通 #

永远不要忽视开发软件的原因:满足真正的需求,解决真正的问题。解决真正需求的唯一方法就是去跟有真正需求的人沟通,让他们参与进来。

06. 开发者与客户目标一致 #

从客户的角度出发,按优先级对需求排序,确保不要 delay。

07. 开发正确的原型 #

有两种原型,一次性原型和演进式原型。

  • 一次性原型:用快速粗糙的方式构建,交给客户来获得反馈,得到反馈后废弃,然后获取正规的需求后再开发。
  • 演进式原型:用高质量的方式构建,交给客户获取反馈,然后进行整改。

如果对大多数功能都不了解,应该首先构建一个一次性原型,然后从零开始构建一个演进式原型。

注意 #

  • 开发一次性原型要快,不用担心质量,可以使用任何工具任何语言,只需要开发那些没有充分理解的特性。
  • 开发演进式模型时,从小的可用系统开始,只实现少数功能,然后逐步扩展,覆盖更多的功能子集,这样可降低风险。

08. 为变化做好准备 #

开发过程中的变化是不可避免的,可能体现在新的代码、新的测试计划、新的需求或需求变更等,不要抱怨,积极应对,做好准备。

09. 简短的用户手册 #

即简短的文档,文档内容越少,软件质量越高,这里不是说要少写文档,而是要做高质量的软件,让用户尽量少看文档就能使用明白。

10. “知道何时"比"知道如何"重要 #

一个工程师要了解更多的技术,要知道什么时候使用什么技术,要知道什么项目使用什么项目。

11. 跟风要小心 #

当学习新技术时,不要轻易接受与之相关的不可避免的炒作。

12. 不要忽视技术 #

不要固步自封,紧跟技术潮流,每年努力参加 1-2 个关键会议。与参会者的交流,很可能比会议报告更重要。

13. 使用文档标准 #

如果你的项目、组织或客户要求遵循一套文档标准,那就要遵循它,理智的执行。

14. 承担责任 #

软件有任何问题时,不要找任何借口,要承担责任,要么做好,要么就不做。

15. 先确定问题,再写需求 #

先明白要解决的是什么问题,再提出相关的需求。

16. 修复需求规格说明中的错误 #

  • 如果错误保持到系统设计阶段,定位和修复要多花 5 倍的代价
  • 如果保持到编码阶段,要多花 10 倍的代价
  • 如果保持到单元测试阶段,要多花 20 倍的代价
  • 如果保持到交付阶段,要多花 200 倍的代价

17. 记录需求为什么被引入 #

记录每个需求的动机。

18. 给需求排列优先级 #

并非所有需求都是同等重要的,要明确需求的优先级,先做哪个需求,后做哪个需求,或者在关键阶段哪个需求可以暂时舍弃掉。

19. 明确环境超出预期时的系统行为 #

当环境超出为其定义的任何约束时,在软件需求规格说明中应明确声明预期的系统响应。用我们开发者的话说就是,做好边界处理。

20. 评估备选方案 #

设计架构或者某个解决方案时,最好详细列出多种方法,明确优缺点,在这些方法之间权衡分析,最终选择一种。

21. 做好封装 #

面向对象的一种思想,对某一需求做好抽象,做好封装,做好信息隐藏。

22. 不要重复造轮子 #

程序员经常一次又一次的重新发明组件,却很少修补已有的组件。

23. 保持简单 #

构建软件设计有两种办法,一种办法是使它简单到明显没有缺陷,另一种办法是使它复杂到没有明显的缺陷。

24. 保持概念一致 #

这是高质量设计的一个特点,方式一定要统一,包括模块如何向调用方通知错误,软件如何向用户通知错误,如何组织数据结构,模块通信机制,文档标准等等。

25. 使用耦合和内聚 #

尽量做到高内聚低耦合。高耦合意味着,当修改一个组件时,很可能需要修改其他组件。低内聚意味着,难以分离出错误原因或者难以判断为满足新需求而要修改的位置。

26. 为变化而设计 #

需要选择合适的架构、组件和技术来适应不断的变化,设计需要做到:

  • 模块化:产品由独立部分组成,每一部分都可以单独升级和替换,对其他部分造成最小的影响。
  • 可移植性:产品应该很容易修改以适应新的硬件和操作系统。
  • 可塑性:产品可以灵活适应预期外的新需求。

28. 软件的通用性和灵活性 #

通用性体现在,在不同的场景下不做任何修改就能执行预期功能。灵活性体现在,它很容易被修改,以在不同的场景下执行其功能。

29. 使用高效的算法 #

了解算法复杂度是成为优秀软件工程师的必要前提。高效的算法和低效的算法可能会相差几个数量级。

30. 避免使用特殊技巧 #

很多程序员喜欢编写比较 trick 的代码,然而这种程序让别人很难理解,也很难维护,这种特殊技巧被频繁使用的理由有很多:

  • 程序员都非常聪明,他们想展示这种聪明
  • 维护人员在最终搞清这些特殊技巧如何生效时,不仅会认识到原来的程序员有多聪明,也会意识到自己有多么聪明。
  • 职业安全感。

32. 避免使用全局变量 #

全局变量写代码很方便,但是如果此全局变量访问出现问题,很难确定问题具体出现在哪个模块,所以,可以将重要数据封装在对应模块中,做好封装。

33. 编写可自上而下阅读的程序 #

有助于读者理解。

34. 使用有意义的别名 #

确保每个变量,每个函数的命名都有意义,尽量做到代码即文档,代码即注释。

35. 程序首先是写给人看的 #

程序的功能以及效率固然重要,但程序也是写给人看的,要提升程序的可读性,以免在这个过程中对相关人员造成负面影响。

36. 先确保正确,再提升性能 #

不要担心优化问题,每个项目都有很大的进度压力,在这种情况下,任何时候一个组件要是能够按时完成并且可靠运行,都值得庆祝,先保证完整功能,然后再去考虑做性能优化。

37. 先写文档后写代码 #

也可以理解为,不要上来就埋头写代码,要先想清楚代码应该怎么写,然后再动手。

38. 代码审查 #

即 code review,一定要做 code review,code review 大约会消耗 15% 的研发资源,可以将总成本减少 25%~30%。

39. 避免嵌套太深 #

即圈复杂度不要太高,不过过多的 if-else,switch-case 之类的嵌套,考虑做优化。

40. 编程语言不是接口 #

如果你是一个好的程序员,对任何一种编程语言来说你都应该是一个好程序员。

41. 编程语言的知识没那么重要 #

一个真正优秀的程序员很好的理解和赞赏高质量编程的概念,而不只是了解某些编程语言的语法和语义特性。为一个项目选择语言的首要驱动力应该是什么语言更适合,而不是说我们只知道 C 语言。

42. 格式化代码 #

使用标准的 format 规则,可大大提高程序的可读性。选择遵循哪种规则不重要,但一旦选择了,就要保持一致。

43. 不要太早编码 #

即在编码之前,要确认需求和设计都是正确且合适的,即想清楚再编码。

44. 为代码做单元测试 #

老生常谈了,自己写的代码自己都不测试就去提测,那得多坑啊。

45. 好的管理比好的技术更重要 #

好的管理可以激励人们做到最好,糟糕的管理会打击人们的积极性。

46. 人是成功的关键 #

具备合适经验能力的人,是在预算内按时完成满足用户需求软件的关键。

47. 几个好手要强过很多生手 #

对于关键任务,最好只安排少数有足够经验的工程师,而不是安排许多没有经验的工程师。

48. 不要设定不切实际的 deadline #

要设定合理的 deadline,然后严格踩住。

49. 知晓风险 #

在开始项目时,要熟悉经常导致软件灾难的情况,并制定降低风险的计划:

  • 人员短缺
  • 不切实际的排期
  • 不理解需求
  • 开发糟糕的用户界面
  • 没有控制需求变化
  • 缺乏可重用或接口化的组件
  • 糟糕的响应时间
  • 试图超越当前计算机技术的能力

50. 预先了解风险 #

在项目计划的早期阶段,要梳理与你的项目相关的最大风险列表。

51. 有时重新开始会更好 #

有时候从头开始设计和编码可能是更好的选择。

52. 回归测试 #

每次改动后都要进行回归测试:这个相信大多数程序员都会遵循的一个原则,代码改动后需要验证它是否能够正确的运行。

53. 性能分析 #

在优化前先进行性能分析:先做性能分析,拿到性能数据进行性能分析后再考虑做优化,80-20 原则,80% 的 CPU 周期将被 20% 的代码消耗,我们应该找到那 20% 的代码,然后对它们做优化。