在我们的职业中,在不熟悉的代码库上工作是很常见的。每次加入一个新项目,甚至需要处理大型项目中以前未接触过的部分时,都会发生这种情况。 这种情况不仅限于开发人员必须修复错误;它可以是必须设计新功能的解决方案架构师,也可以是在空闲时间处理 GitHub 问题的开源贡献者。因此,我想描述一下我是如何处理这种情况的,以便让其他人受益。 示例问题 为了说明我的观点,我将使用一个常见的 GitHub 问题来请求开源项目的新功能。 在为 Hazelcast 工作时,我会定期扫描所谓的“良好的第一期”,以便在黑客马拉松上开展工作。我永远无法举办这样的黑客马拉松,但这不是重点。我的想法是帮助有兴趣为开源做贡献的人开始熟悉代码库。 当时,我发现了一个有趣的问题: 添加对 getQuiet 操作的支持 ? http://ehcache.org/apidocs/net/sf/ehcache/Cache.html#getQuiet(java.lang.Object) 这个想法是能够在不接触条目的情况下获取条目,这意味着它不会更新上次访问的时间戳。 它背后的用例是能够在不更改该密钥的驱逐的情况下监视密钥的存在。 -- 分布式地图:添加对getQuiet操作的支持 作为开源贡献者,我将如何处理这项工作? 图表是关键 文档是开始新项目的第一步。在常规项目中,文档可能会丢失、不完整或部分(如果不是全部)误导;在黑客马拉松上,时间可能太短,无法详细阅读。 一般来说,成功的开源项目确实有很好的文档。然而,文档主要面向用户,很少面向开发人员。即使是这种情况,文档解决问题的可能性也很低。 为此,我的切入点是画图。请注意,虽然某些工具可以自动对代码进行逆向工程和绘制图表,但我并不是故意使用它们的。与自动生成的图表相比,手动绘制图表有很多好处: 它侧重于与当前问题相关的代码区域。 它迫使抽屉阅读和理解代码,这是唯一的真实来源。 它构建了我们的代码心智模型。 它记录了我们的发现,以便日后访问。但是,请注意,随着底层代码的发展和双方的分离,文档价值会随着时间的推移而降低。 让我们为问题的代码创建一个图表。首先,我们将在本地克隆 repo 以在我们最喜欢的 IDE 中打开它;唯一需要的功能是当一个人点击一个方法调用时,一个人被定向到该方法。 对于图表本身,请称我为老派,但我仍然喜欢 ,原因有二: UML 序列图 我对他们有一些经验。 语义不是 ,而是在一定程度上由了解 UML 的人共享的。 临时的 话不多说,这里是: 画好图后,我们可以很快定位到问题出在哪里: public abstract class AbstractCacheRecordStore<R extends CacheRecord, CRM extends SampleableCacheRecordMap<Data, R>> implements ICacheRecordStore, EvictionListener<Data, R> { protected long onRecordAccess(Data key, R record, ExpiryPolicy expiryPolicy, long now) { record.setAccessTime(now); // 1 record.incrementAccessHit(); return updateAccessDuration(key, record, expiryPolicy, now); } //... } 读取 ,触发最后访问时间的更新。 DefaultRecordStore Record 解决这个问题不在本文的讨论范围之内。它涉及与更熟悉整体设计的人交谈以开发最佳解决方案。黑客马拉松中的一个好方法是首先提供至少两个备选方案并记录它们各自的权衡。 对于工具,有很多替代品可供选择。我的偏好转到 : PlantUML 它提供了一个 和一个 网络应用程序 Docker 容器 它生成 SVG 或 PNG 图像 可换肤 它是开源且免费的 它定期维护 结论 无论一个人的确切技术角色如何,了解现有代码库都是一项关键技能。创建图表对实现这一目标大有帮助,还有文档的额外好处。 我喜欢 UML 图,因为我熟悉它们,而且它们提供了共享的语义。 因此,如果你想更好地理解一个代码库,你需要的不仅仅是阅读它的代码;你需要画图。 最初于 2023 年 5 月 14 日发表于 A Java Geek