熟悉大型代码库的最佳方法是什么?

时间:2008-10-18 14:04:21

标签: legacy legacy-code codebase

加入一个已经存在大型代码库的现有团队可能会让人望而生畏。什么是最好的方法;

  • 广泛;尝试从代码
  • 中概述所有内容如何链接在一起
  • 窄;一次关注一小段代码,了解它们如何完全运作
  • 选择一项功能,随着您的发展和学习
  • 尝试从类图和uml中获取洞察力(如果有的话)(及时更新)
  • 还有其他什么吗?

我正在开发目前大约20k的线路C ++应用程序&图书馆(编辑:在宏观计划中的小事!)。在工业界,我想你会得到一位经验丰富的程序员的介绍。但是,如果不是这种情况,您可以做些什么来尽快开始增值?

-
答案摘要:

  • 在调试模式中逐步执行代码以查看其工作原理
  • 与比您更熟悉代码库的人配对,轮流成为编码人员和观看/讨论的人。在团队成员之间轮换合作伙伴,以便知识得到传播。
  • 编写单元测试。首先断言您认为代码的工作方式。如果结果如你所愿,你可能已经理解了代码。如果没有,你有一个难题要解决,或者要进行调查。 (感谢Donal,这是一个很好的答案)
  • 以类似于上面
  • 的方式,通过现有的功能代码单元测试
  • 阅读UML,Doxygen生成的类图和其他文档,以获得对代码的广泛感受。
  • 进行小编辑或错误修复,然后逐步建立
  • 记录笔记,不要跳入并开始开发;花时间理解比生成凌乱或不合适的代码更有价值。

这篇文章是the-best-way-to-familiarize-yourself-with-an-inherited-codebase

的部分副本

19 个答案:

答案 0 :(得分:24)

如果可能的话,先从一些小任务开始,根据问题调试代码。 在调试模式中单步执行代码是了解某些工作原理的最简单方法。

答案 1 :(得分:17)

另一个选择是为您感兴趣的功能编写测试。设置测试工具是确定系统具有哪些依赖关系及其状态所在位置的好方法。每个测试都以关于您认为系统应该工作的方式的断言开始。如果事实证明是这样的话,那么你已经取得了一些成就,并且你已经有了一些工作示例代码来重现它。如果它不起作用,你就有一个难题需要解决,并且需要进行一系列调查。

答案 2 :(得分:10)

我通常向尚未提及的人建议的一件事是,在成为开发人员之前,成为现有代码库的合格用户非常重要。当新的开发人员进入我们的大型软件项目时,我建议他们在尝试使用代码之前花时间成为专家用户。

也许这很明显,但我看到很多人都试图过快地加入代码,因为他们渴望开始取得进展。

答案 3 :(得分:9)

这完全取决于你是什么类型的学习者和什么样的程序员,但是:

  • 广泛的第一 - 你需要了解范围和规模。这可能包括略读文档/ uml,如果它们是好的。如果这是一个长期项目,并且您需要完全理解所有内容,我可能会真正正确地阅读文档。再次,如果他们是好的。
  • 缩小 - 选择可管理的东西并尝试理解它。获得代码的“品味”。
  • 选择一个功能 - 如果您有信心,可能会与您刚看到的功能不同,并开始做一些小改动。
  • 迭代 - 评估事情的进展情况,看看你是否可以从更深入的重复早期步骤中受益。

答案 4 :(得分:7)

配对严格轮换。

如果可能的话,在浏览文档/代码库时,尝试使用严格轮换的配对。意思是,你们两个坐在一起一段固定的时间(比如说,一个2小时的会话),然后你切换成对,一个人将继续处理该任务,而另一个人则转移到另一个合作伙伴的另一个任务。

成对的你将获得一条知识,然后可以在轮换发生时将其提供给团队的其他成员。同样有益的是,当一对新人聚集在一起时,从事该任务的人(在这种情况下,调查代码)可以以更容易理解的方式总结和解释这些概念。随着时间的推移,每个人都应该处于相似的理解水平,并希望避免“哦,只有约翰知道那段代码”综合症。

从我可以告诉你的情况来看,你有一个很好的数字(3对),但是,如果你是分发的,或者没有工作到相同的时间表,那么这是不可能的。

答案 5 :(得分:6)

我建议在其上运行Doxygen以获取最新的类图,然后进行广泛的一段时间。这为您提供了一个快速的大图片,您可以在使用代码时近距离和肮脏地使用它。

答案 6 :(得分:4)

我同意这完全取决于你是哪种学习者。话虽如此,我一直在两家公司开始拥有非常庞大的代码库。通常,我这样工作:

如果可能的话,在查看任何功能代码之前,我会进行已编写的单元测试。这些通常可以帮助很多。如果它们不可用,那么我会执行以下操作。

首先,我在很大程度上忽略了实现,只关注头文件或类接口。我试着了解每个班级的目的是什么。其次,我从实际上看起来最重要的领域开始深入实施。这很难衡量,所以偶尔我会从顶部开始,然后在文件列表中向下工作。我称之为广度优先学习。在这个初始步骤之后,我通常会深入了解其余的代码。最初的广度优先看起来有助于巩固/修复我从界面级别获得的任何想法,然后深度方式的外观向我展示了用于实现系统的模式,以及不同的设计思想。深度优先,我的意思是你基本上使用调试器逐步完成程序,逐步进入每个函数以查看它是如何工作的,等等。对于非常大的系统来说,这显然是不可能的,但20k LOC并不是那么多。 :)

答案 7 :(得分:3)

与熟悉系统的其他程序员合作开发新功能或修复错误。这是我见过最好的方法。

答案 8 :(得分:2)

我认为您需要将此与特定任务联系起来。当你有时间在你的手上时,请选择你想要的任何方法。

当你有需要完成的事情时,给自己一个狭隘的焦点并完成它。

答案 9 :(得分:2)

我有类似的情况。我会说你这样:

  • 如果它是一个数据库驱动的应用程序,从数据库开始,尝试理解每个表,它的字段,然后它与其他表的关系。
  • 一旦使用底层商店,请移至ORM层。那些表必须在代码中有某种表示。
  • 完成后,继续研究这些对象的来源和来源。接口?什么接口?有任何验证吗?在进入数据存储区之前对它们进行了哪些预处理?

这将使您更熟悉系统。请记住,尝试编写或理解单元测试只有在您非常了解正在测试的以及为什么需要仅在 中进行测试时才有可能。 >那样。

如果大型应用程序没有推向数据库,我建议采用其他方法:

  • 系统的主要目标是什么?
  • 系统的主要组成部分是什么来解决这个问题?
  • 每个组件之间有哪些相互作用?制作描绘组件依赖关系的图表。问一个已经在做的人。这些组件必须在彼此之间交换内容,因此也要尝试找出它们(比如IO可能会将File对象返回到GUI等)
  • 一旦对此感到满意,请深入了解其中最不依赖的组件。现在研究如何将该组件进一步划分为类以及它们如何相互作用。通过这种方式,您可以完全掌握单个组件
  • 转到下一个最不依赖的组件
  • 最后,转移到核心组件,该组件通常会依赖于您已经解决的许多其他组件
  • 在查看核心组件时,您可能会回顾之前检查过的组件,所以不要担心继续努力!

对于第一个策略: 以这个stackoverflow站点为例。检查数据存储区,存储内容,存储方式,代码中代码的表示形式,UI上的显示位置。他们来自哪里,以及他们回到数据存储区后对他们进行的处理。

第二个 以文字处理器为例。有哪些组件? IO,UI,Page等。这些是如何相互作用的?随着你的进一步学习,继续前进。

放松。书面代码是某人的心态,冻结了逻辑和思维方式,阅读这种思想需要时间。

答案 10 :(得分:2)

首先要了解“问题域”(是工资单系统?库存?实时控制还是其他)。如果您不理解用户使用的术语,您将永远不会理解代码。

然后看对象模型;可能已经存在图表,或者您可能需要对其进行反向工程(手动或使用Doug建议的工具)。在这个阶段,您还可以调查数据库(如果有的话),是否应该遵循对象模型,但可能不会,并且知道这一点非常重要。

查看更改历史记录或错误数据库,如果有一个区域出现很多,请先查看该位。这并不意味着写得不好,而是每个人都使用它。

最后,保留一些笔记(我更喜欢维基)。

  • 现有的家伙可以用它来理智地检查你的假设并帮助你。
  • 您需要稍后再参考。
  • 团队中的下一个新人真的会感谢你。

答案 11 :(得分:2)

您可能需要考虑查看源代码逆向工程工具。我知道有两种工具:

这两个工具都提供类似的功能集,其中包括静态分析,可生成软件中模块之间关系的图形。

这主要包括呼叫图和类型/类别的优先级。查看此信息可以让您很好地了解代码的各个部分之间的关​​系。使用这些信息,您可以深入了解您最感兴趣的部分的实际来源,以及您需要首先理解/修改的部分。

答案 12 :(得分:2)

如果它有单元测试(我打赌它没有)。从小处开始,确保单元测试不会失败。如果你立刻盯着整个代码库,你的眼睛会茫然,你会感到不知所措。

如果没有单元测试,则需要关注所需的功能。运行该应用并查看您的功能应该影响的内容的结果。然后开始查看代码,试图找出应用程序如何创建您想要更改的内容。最后更改它并检查结果是否按照您想要的方式出现。

你提到它是一个应用程序和一个库。首先更改应用程序并坚持使用库作为用户。然后,在您学习了库之后,它将更容易更改。

从上到下的方法,应用程序可能有一个主循环或主gui控制所有动作。值得了解应用程序的主要控制流程。值得阅读代码,以便自己对应用程序的主要流程进行全面概述。如果它是一个GUI应用程序,则创建一个纸张,显示哪些屏幕以及如何从一个屏幕到另一个屏幕。如果它是命令行应用程序,则处理如何完成。

即使在公司中,采用这种方法并不罕见。通常没有人完全理解应用程序的工作原理。人们没有时间带你去看看。他们更喜欢有关特定事物的具体问题,因此您必须自己深入研究并进行实验。然后,一旦得到您的具体问题,您可以尝试隔离该应用程序的知识来源并提出问题。

答案 13 :(得分:2)

让团队为您安排错误修复两周(如果您有两周时间)。他们会很乐意让某人为此负责,到那个时期结束时,你将花费大量时间解决问题,你可能会很清楚地知道它。

答案 14 :(得分:2)

首先,如果您有可以使用代码经验的团队成员,您应该安排他们与您一起概述代码。每个团队成员都应该向您提供有关其专业领域的信息。让多个人解释事物通常很有价值,因为有些人会比其他人更善于解释,有些人会比其他人有更好的理解。

然后,您需要在没有任何压力的情况下开始阅读代码一段时间(如果您的老板会提供,那就是几天或一周)。它通常有助于自己编译/构建项目,并能够以调试模式运行项目,以便您可以单步执行代码。然后,开始让你的脚湿润,修复小虫子并进行小的改进。您很快就会为一个中型项目做好准备,后来又成为一个大项目。继续依靠你的队友 - 通常你可以找到一个愿意指导你的人。

如果你挣扎,不要对自己太过刻苦 - 这是正常的。理解大型代码库可能需要很长时间,甚至数年。实际上,通常的情况是,即使经过多年,代码的某些部分仍然有点可怕和不透明。当您在项目之间停工时,您可以深入了解这些区域,并且您经常会发现经过几次尝试后您甚至可以找出这些零件。

祝你好运!

答案 15 :(得分:1)

我发现只是跳入代码可能有点压倒性。尝试尽可能多地阅读有关设计的文档。这有望解释每个组件的目的和结构。如果现有的开发人员可以指导您完成它,那是最好的,但这并非总是可行。

一旦您熟悉代码的高级结构,请尝试修复一两个错误。这将帮助您掌握实际代码。

答案 16 :(得分:1)

我喜欢所有的答案,说你应该使用像Doxygen这样的工具来获取类图,并首先尝试理解大局。我完全同意这一点。

尽管如此,这在很大程度上取决于代码的开始考虑因素。如果它是一个巨大的混乱,它将很难学习。如果它干净整洁,组织得当,那应该不会那么糟糕。

答案 17 :(得分:1)

请参阅this answer,了解如何使用测试覆盖率工具查找感兴趣的功能的代码,而不了解该功能的位置,或者它是如何在多个模块中传播的。

答案 18 :(得分:0)

(无耻的营销)

你应该看看nWire。它是一个Eclipse插件,用于导航和可视化大型代码库。我们的许多客户通过打印主要流程的可视化来使用它来打入新的开发人员。