软件公司如何有效管理代码复杂度:实用策略与团队协作

本文深入探讨软件公司中代码复杂度的管理策略,强调个体程序员的关键作用,提供从问题识别到优先级排序的具体步骤,帮助团队持续改进代码质量并提升开发效率。

如何应对软件公司的代码复杂度

作者: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 设计