软件公司如何有效管理代码复杂度

本文探讨了软件公司中代码复杂度的管理策略,强调个体程序员在解决复杂度中的核心作用,并提供了从问题识别到优先级排序的具体方法,包括团队协作和持续改进的实际步骤。

软件公司如何有效管理代码复杂度

作者:Max Kanat-Alexander
发布日期:2015年1月6日

这里有一个显而易见的陈述,但具有一些微妙的后果:只有个体程序员才能解决代码复杂度。

也就是说,解决代码复杂度需要个体对代码的关注。他们当然可以使用适当的工具来简化任务,但最终,简化代码的是人类智能、注意力和工作的应用。

那么,这为什么重要?更明确地说:解决代码复杂度通常需要在个体贡献者层面进行详细的工作。

如果经理只是说“简化代码!”然后就不管了,通常什么也不会发生,因为(a)他们不够具体,(b)他们不一定具备关于每个代码片段的具体知识来做到那么具体,以及(c)理解问题的一部分实际上是解决问题的过程,而经理不是编写解决方案的人。

经理在公司中的级别越高,这一点就越真实。当CTO、副总裁或工程总监给出像“提高代码质量”这样的指令,但没有更具体时,往往会发生的是公司里有很多动作,但代码库并没有显著改善。

如果你是一名软件工程经理,很容易提出影响广泛领域的广泛解决方案。这种方法在代码复杂度上的问题是,问题通常由许多不同的小项目组成,需要个体程序员的详细工作。因此,如果你尝试用相同的广泛解决方案处理所有事情,该解决方案将不适合大多数需要处理的情况。你的广泛解决方案尝试实际上会适得其反,软件工程师会感觉他们做了很多工作,但实际上没有产生可维护、简单的代码库。(这是软件管理中的常见模式,它助长了代码复杂度是不可避免且无法解决的错误信念。)

那么,作为经理,如果你有一个复杂的代码库并想解决它,你能做什么?诀窍是从个体贡献者那里获取数据,然后与他们合作帮助他们解决问题。大致流程如下:

  1. 收集问题列表:要求团队中的每个成员写下他们对代码感到沮丧的事情列表。代码复杂度的症状包括对代码的情绪反应、对代码的困惑、感觉修改某部分会破坏它、优化困难等。所以你想得到诸如“系统中是否有部分在修改时让你紧张?”或“代码库的某些部分是否让你感到沮丧?”等问题的答案。

    每个软件工程师应该写下自己的列表。我不建议实施某种系统来收集列表——只需让人们以最简单的方式为自己写下问题。给他们几天时间写这个列表;他们可能会随着时间的推移想到其他事情。

    列表不必只关于你自己的代码库,还可以是关于开发者必须使用或工作的任何代码。

    此时你寻找的是症状,而不是原因。开发者可以尽可能笼统或具体地列出。

  2. 召开团队会议:与团队召开会议,让每个人带上他们的列表和可以访问代码库的计算机。这种团队会议的理想规模大约是六到七人,因此你可能需要将其分解为子团队。

    在会议中,你要审查列表,并为每个症状关联一个具体的目录、文件、类、方法或代码块的名称。即使有人说“整个代码库没有单元测试”,你也可以说“告诉我一个具体的时间这对你产生了影响”,并用回应来缩小当前最需要编写单元测试的文件范围。

    你还要确保你真正得到问题的描述,可能更像是“重构代码库很困难,因为我不知道是否破坏了其他人的模块。”然后单元测试可能是解决方案,但你首先想尽可能缩小问题的具体位置。(确实,几乎所有代码都应该进行单元测试,但如果你没有任何单元测试,你需要从一些可行的任务开始。)

    总的来说,这里的想法是只有代码才能实际修复,所以你必须知道哪部分代码是问题。可能存在广泛的问题,但该问题可以分解为受影响的特定代码片段的具体问题,一个一个地处理。

  3. 提交问题报告:使用会议中的信息,为每个命名的目录、文件、类等提交一个描述问题(而不是解决方案,只是问题!)的bug报告。一个bug可以简单到“FrobberFactory难以理解”。

    如果在会议中提出了解决方案,你可以在bug中注明,但bug本身应主要关于问题。

  4. 优先级排序:现在该确定优先级了。首先要做的是查看哪些问题影响最多开发者且最严重。那些是高优先级问题。通常优先级排序的这一部分由对团队或公司开发者有广泛视野的人完成。通常,这是经理。

    也就是说,有时问题的解决顺序与它们的严重性不直接相关。例如,问题X必须在问题Y之前解决,或者解决问题A会使解决问题B更容易。这意味着问题A和X应该首先修复,即使它们不如它们阻塞的问题严重。通常,存在这样的问题链,诀窍是找到堆栈底部的问题。错误处理优先级排序的这一部分是软件设计中最常见和主要的错误之一。它可能看起来是一个小细节,但实际上对于解决复杂度的成功至关重要。在所有情况下,良好软件设计的本质是以正确的顺序采取正确的行动。强迫开发者不按顺序处理问题(不考虑哪些问题 underlying 其他问题)会导致代码复杂度。

    优先级排序的这一部分是一项技术任务,通常最好由团队的技术负责人完成。有时这是经理,但其他时候是高级软件工程师。

    有时,直到你在某段代码上进行开发并发现先修复另一段代码会更容易时,你才真正知道该先处理哪个问题。话虽如此,如果你能提前确定顺序,那很好。但如果你发现你必须实际找出解决方案才能确定顺序,那就暂时跳过它。

    无论你是提前做还是在开发过程中做,个体程序员必须意识到在他们被分配的任务之前有一个 underlying 任务要处理。他们必须有权从当前任务切换到实际阻塞他们的任务。这有一个限制(例如,为了修复一个文件而将整个系统重写为另一种语言不是好的时间利用),但通常,“找到堆栈底部的问题”是开发者在进行这类清理时最重要的任务之一。

  5. 分配任务:现在你将每个bug分配给个体贡献者。这是一个相当标准的管理过程,虽然它肯定涉及一些详细的工作和沟通,但我想大多数软件工程经理已经熟悉如何做。

    这里的一个棘手部分是,一些bug可能关于不由你的团队维护的代码。在这种情况下,你必须通过组织适当工作,让适当的团队对问题负责。在这里,与另一个团队共同的经理的支持会有所帮助。

    在一些组织中,如果其他团队的问题不太复杂或详细,你的团队也可能自己进行更改。这是一个你可以根据整体生产力做出的判断调用。

  6. 安排处理时间:现在你已经提交了所有这些bug,你必须弄清楚何时处理它们。通常,正确的事情是确保开发者定期修复你提交的一些代码质量问题以及他们的功能工作。

    如果你的团队为一段时间(如一个季度或六周)制定计划,你应该在每个计划中包含一些代码清理。最好的方法是让开发者首先进行会使他们的特定功能工作更容易的清理,然后让他们进行功能工作。通常这甚至不会减慢他们的整体功能工作。(也就是说,如果做得正确,开发者通常可以在一个季度内完成相同数量的功能工作,即使他们也在进行代码清理,这证明代码清理已经在提高生产力。)

    不要完全停止正常的功能开发来只处理代码质量。相反,确保有足够的代码质量工作持续进行,使代码库的质量始终在整体上提高,而不是随着时间的推移变得更糟。

如果你做这些事情,你应该会走上实际改进代码库的道路。实际上,关于这个过程有很多需要了解——可能足够写另一整本书。然而,上述内容加上一些常识和经验应该足以在你的代码库质量上做出重大改进,甚至可能改善你作为软件工程师或经理的生活。

-Max

附言:如果你确实需要更多帮助,我很乐意来你的公司演讲。只需让我知道。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计