软件设计哲学的教训

2025-06-07

软件设计哲学的教训

我最近读完了John Ousterhout 的《软件设计哲学》 。如果你喜欢《代码整洁之道》《程序员修炼之道》,你很可能也会喜欢这本书。它与那些书非常相似,内容也有一些重叠,主要关注的是好的软件设计与坏的软件设计之间的区别。

我读科技书籍的时候,总会做笔记,并标出那些让我产生共鸣的段落。这有助于我记住那些有意义的信息。我在下面复制了大部分笔记,希望你也能找到一些能引起共鸣的内容。

享受!

关于编码建议

当您不同意某人的编码建议(本书或《清洁代码》中的内容)时,请尝试理解您不同意的原因。

每条规则都有例外,每条原则都有其局限性。如果你把任何设计理念推向极端,最终都可能适得其反。

复杂

复杂性对读者来说比对作者来说更显而易见。如果你写了一段代码,你觉得它很简单,但其他人却觉得它很复杂,那么它就是复杂的。当你发现自己处于这种情况时,值得向其他开发者探究一下,为什么这段代码在他们看来很复杂;从你和他们的观点之间的差异中,或许可以学到一些有趣的道理。作为一名开发者,你的工作不仅仅是编写自己可以轻松使用的代码,还要编写其他人也可以轻松使用的代码。

复杂性的症状

  • 变更放大:看似简单的变更需要在许多不同的地方修改代码
  • 认知负荷:开发人员为了完成一项任务需要知道多少
  • 未知的未知数:不清楚哪些代码片段需要修改才能完成任务

好的设计应该是显而易见的。

模块、接口和实现

模块应该很深。复杂的实现应该隐藏在简单的接口背后,并提供合理的默认值,以适应最常见的用例。

“最好的功能是那些你甚至都不知道其存在的功能。”

“作为模块开发人员,您应该努力使模块用户的生活尽可能轻松,即使这意味着您需要做额外的工作。”

“减少必须处理异常的地方的数量。”

设计方法

软件设计很难,所以你最初关于如何构建模块或系统的想法不太可能产生最佳设计。如果你在每个主要设计决策上都考虑多种选择,最终会得到更好的结果。

尝试选择截然不同的方法;这样你会学到更多。即使你确定只有一种合理的方法,也要考虑第二种设计,无论你认为它有多糟糕。思考该设计的弱点,并将其与其他设计的特点进行对比,将会很有启发。

评论和文档

注释应该用来解释那些无法用代码表达的事情,比如做出某个决定的理由。

“跨模块文档的最大挑战是找到一个开发人员可以自然发现的地方。”

一致性、约定和编码风格

“一致性创造了认知杠杆:一旦你了解了在一个地方如何做某事,你就可以运用这些知识立即了解使用相同方法的其他地方。”

记录编码约定和代码风格偏好。尽可能地自动化和强制执行,例如使用 ESLint 和 Prettier。加入新公司或新团队时,请遵循现有的约定。为了使用新的约定而重构或重写所有代码几乎不值得。

战术与战略编程;同样敏捷

战术性规划 vs. 战略性规划。不要只专注于小改动,以免将来的变更更加困难。

敏捷开发的风险之一是它可能导致战术性编程。敏捷开发倾向于让开发人员专注于功能而非抽象,并鼓励开发人员推迟设计决策,以便尽快开发出可运行的软件。例如,一些敏捷实践者认为,不应立即实现通用机制;而应先实现一个最小化的专用机制,等到确定需要时再重构为更通用的机制。虽然这些论点在一定程度上有道理,但它们违背了投资原则,并且鼓励一种更具战术性的编程风格。这可能会导致复杂性迅速积累。

测试的重要性

测试,尤其是单元测试,在软件设计中扮演着重要的角色,因为它们有助于重构。如果没有测试套件,对系统进行重大的结构性更改将非常危险。由于查找错误的方法并不简单,因此错误很可能在新代码部署之前都无法检测到,而部署新代码后查找和修复错误的成本要高得多。因此,开发人员会避免在没有良好测试套件的系统中重构;他们会尝试尽量减少每个新功能或错误修复所需的代码更改次数,这意味着复杂性会不断累积,设计错误也无法得到纠正。

有了一套完善的测试,开发人员在重构时就能更有信心,因为测试套件能够发现大多数引入的错误。这鼓励开发人员对系统进行结构性改进,从而实现更优的设计。单元测试尤其有价值:它们比系统测试提供更高的代码覆盖率,因此更有可能发现任何错误。

性能改进

在进行性能改进之前,请先衡量所需性能,以便为现有性能创建基准。我们对哪些改进会提升性能的直觉有时是错误的,这些改进要么没有任何实际意义,要么实际上反而会降低性能。

围绕关键路径设计代码。即使其他环节的性能提升并非最大的瓶颈,但当你遇到关键路径的这一部分时,仍然会造成瓶颈。

结论和良好设计的好处

你在优秀设计上的投资很快就会得到回报。你在项目初期精心定义的模块,在日后反复复用时,会为你节省时间。你六个月前编写的清晰文档,在回头添加新功能时,也能为你节省时间。你花在磨练设计技能上的时间也会得到回报:随着技能和经验的增长,你会发现自己能够越来越快地创作出优秀的设计。一旦你掌握了方法,优秀的设计并不比草率的设计花费太多时间。

成为一名优秀设计师的回报是,你可以将更多的时间投入到设计阶段,这很有趣。差劲的设计师大部分时间都花在了复杂而脆弱的代码中寻找bug上。如果你提升了设计技能,你不仅能更快地开发出更高质量的软件,而且软件开发过程也会更加愉快。

文章来源:https://dev.to/thawkin3/lessons-from-a-philosophy-of-software-design-4cn7
PREV
作为一名软件工程师你能学到的最重要的一件事
NEXT
如何使用 Slash GraphQL 后端构建 Pokédex React 应用程序