原文:https://matklad.github.io/2021/02/06/ARCHITECTURE.md.html
作者:Alex Kladov
译者:ChatGPT 4 Turbo
如果你维护一个 10k-200k 行代码的开源项目,我强烈建议你在 README
和 CONTRIBUTING
旁边添加一个 ARCHITECTURE
文档。在详细解释为什么以及如何做之前,我想强调这不是另一个“文档很好,多写文档”的建议。我在文档方面相当马虎,例如,我经常仅使用“简化”作为提交信息。尽管如此,我对这个问题非常重视,甚至到了纠缠你的程度 🙂
我既有为开源项目做出贡献的经验,也有维护它们的经验。我学到的一个教训是,偶尔的贡献者和核心开发者之间最大的区别在于对项目物理架构的了解。大致来说,如果你不熟悉项目,编写一个补丁可能需要多花 2 倍的时间,但要弄清楚应该在哪里修改代码可能需要多花 10 倍的时间。如果你已经和项目打交道一段时间,这种差异可能难以察觉。如果我对一个代码库是新手,我会按照某种伪随机顺序阅读每个文件,视为一系列逻辑块。如果我之前已经做出了重大贡献,感知就完全不同了。我脑中有了一张代码的心智图,所以我不再按顺序阅读。相反,我直接跳到应该修改的地方,如果它不在那里,我就移动它。一个人的心智图是真理的源泉。
我认为 ARCHITECTURE
文件是一种低投入高杠杆的方式来弥合这一差距。正如名称所暗示的,这个文件应该描述项目的高层架构。保持简短:每个经常贡献的人都将不得不阅读它。此外,它越短,将来的某些变更使其失效的可能性就越小。这是 ARCHITECTURE
的主要经验法则 —— 只指定那些不太可能频繁变更的事项。不要试图让它与代码保持同步。相反,每年回顾它几次。
从鸟瞰图开始概述正在解决的问题。然后,指定一个或多或少详细的代码图。描述粗粒度模块以及它们之间的关系。代码图应该回答“做 X 的东西在哪里?”。它还应该回答“我正在看的这个东西是做什么的?”。避免深入每个模块的工作细节,将这些内容拉到单独的文档中或(更好的是)内联文档中。代码图是一个国家的地图,而不是其各州地图的地图集。利用这个机会反思项目结构。在代码图中你想要彼此靠近的东西,在你运行 tree .
时它们是相邻的吗?
请为重要的文件、模块和类型命名。不要直接链接它们(链接会过时)。相反,鼓励读者使用符号搜索通过名称找到提到的实体。这不需要维护,并将有助于发现相关的、同名的事物。
明确指出架构不变性。通常,重要的不变性表现为某些事物的缺失,而从阅读代码中很难直接发现这一点。想想 web 开发中的一个常见例子:模型层陷入不会依赖视图层。
请指出层与系统之间的边界。边界隐含地包含了其后系统实现的信息。它甚至限制了所有可能的实现。但是,仅仅通过随机查看代码来找到边界是困难的——好的边界具有零测度。
在完成代码图后,添加一个关于横切关注点的单独部分。
一个很好的 ARCHITECTURE
文档示例是来自 rust-analyzer 的:architecture.md。
这篇文章是《十万行 Rust 代码》系列的一部分。