X射线软件设计要点

2020-07-06 03:48:33

在他的书[软件设计X射线](https://www.google.com/search?q=software+design+x-rays&;oq=soft,亚当·托恩希尔)中,他提出了一种非常独特的方法来回答这些问题。它混合了软件架构和人类心理,产生了处理大型代码库的强大技术。

我读过你的代码,是同一个人写的犯罪现场。这有什么不同呢?

嗯,“软件设计X射线”是在“你的代码作为犯罪现场”之后写的。虽然这本书的取证味道很有趣,但亚当不再过多地提到它,以避免让读者分心。内容要精致得多!

让我总结一下这本书的内容,以及为什么我认为它可以帮助你:

为此,亚当提出了一种称为行为代码分析的技术。它使用您的版本控制系统(VCS)中包含的信息来帮助您在大型代码库上做出明智的决策。

如果你不需要维护技术债务,那么它其实不是问题。

静态分析工具将所有债务视为等值。他们报告了无数的代码气味,您别无选择,只能专注于关键的代码。尽管如此,还有很多东西需要清理!

这就是为什么您应该使用时间维度来识别热点:如果您想要超级有效,那么您应该在大型代码库中重点关注重构工作的地方。

如果您想了解如何生成和使用它们,我详细介绍了这些技术:

有趣的是,热点往往停留在这里,因为人们害怕解决它们。因此,它们会吸引更多的复杂性,并成为问题的瓶颈。

当涉及到评估代码的复杂性时,许多指标相互竞争。最流行的可能是圈复杂度。然而,有趣的是,代码行数(LOC)的计数通常是一个足够好的指示器!

因为它是语言中立的度量,所以无论您的语言工具是什么,生成它都非常容易。为此,您可以使用cloc:

另一个运行良好的与语言无关的度量是缩进级别。缩进具有逻辑拆分的含义。这是一个很好的指标,表明代码很复杂。

只有当您在项目历史记录中更改了编码样式时,才能使用这些代码。但是因为这些指标很简单,所以查看特定值和阈值是没有意义的。重要的是趋势。通常这就足够了。

如果您分析一个文件的复杂性随时间的演变,您就会了解该文件的情况:

这有助于向非技术经理展示重构的影响。这有助于他们直观地看到这类工作的效果,以及对团队生产力的影响。

一旦确定了热点,您就可以在文件级应用相同的逻辑来查找复杂的函数:

这就是亚当所说的“X射线分析”。下面是粗略的食谱:

将diff结果与此版本中存在的函数进行匹配(这里需要解析代码)。

使用HotSpot+X-Ray技术,您可以将400kLOC代码库放在几百行代码上,如果它们被重构,它们将会产生最大的影响。

很高兴知道您可以使用-L选项使用git日志执行廉价的X光检查:

当您分析代码以评估其设计时,通常会忘记时间维度。那是个错误!更改耦合是指文件随时间一起更改。

2个文件可能会一起意外更改。但是,如果它们在多次提交中一起更改,并且具有高度耦合性,那么这两个文件很有可能是耦合的!

这可以让你识别出经验上属于一起的东西。如果这些文件不在同一位置,则当前设计可能存在问题。可能存在糟糕的抽象,或者可能存在不断进化的复制粘贴代码。

因为您使用Git元数据来确定这些耦合,所以它与语言无关。因此,您可以检测跨堆栈的耦合,例如前端和后端之间的耦合。

此技术的限制是开发人员使用的提交模式。如果开发人员总是独立提交测试和代码,您可以采用该技术,并将同一作者在24小时滑动窗口中的提交视为“耦合在一起”。通常情况下,这就足够了。

只有当您需要同时更改所有事件时,这才是不好的。因此,如果您在更改耦合分析中集成了相似性度量,则可以检测出有问题的复制-粘贴:

修复代码重复通常是一件轻而易举的事。它有助于开始重构热点。

当您遇到非常旧的代码时,您可以将其封装到库中并从代码库中提取它。需要处理的代码更少,这对开发人员和入门人员都有好处!

代码不稳定是有问题的。这通常意味着你需要修补它。因为您不是很了解它,所以很有可能因为无知而产生错误。通过创建更多的bug,您需要再次更新代码:它不稳定。

使用git log-l--format=";%ad";--date=Short--path/to/file获取每个文件的上次修改日期。

如果代码库在一段时间内没有维护,则认为最年轻的代码库为0。

在相同的包中,您可以识别不同年龄的代码(非常旧的和非常新的)。试着理解为什么有些代码无法稳定。

也许你能提取出它的一部分,它实际上会稳定下来。

也许您会识别出混合在一起的不同概念。因此,您可以重构代码的结构:

当您将太多的开发人员放在同一代码上时,很难保持高效率。这是因为代码不断变化:您三天前编写的代码现在不同了,所以您必须不断地重新发现它的功能。错误的风险很高。

这就是为什么如果你把更多的人放在一个延迟的项目上,这个项目就会更晚。

在过去的3个月里,你有很多次要的贡献者=有错误的机会更高。

这是因为贡献者对他们所做的改变没有完整的背景。

对于许多贡献者,责任的分散会使代码库腐烂,因为每个开发人员都认为其他人会负责重构。

因此,您需要引入责任领域来赋予团队完全所有权。其他团队可能会通过PR做出贡献,但一个团队应该拥有自己的一部分,参与评审,并拥有最终决定权。

最后,团队应该有比他们的操作边界(他们改变的)更宽的知识边界(他们知道的)。您可以通过以下方式实现这一点:

您可以统计git中特定代码部分的开发人员数量:

如果您分析代码的一部分上的贡献分布,您会得到一个扩散分数:

架构决策记录(ADR)对于简单地跟踪项目中的架构决策非常有用。

它们帮助人们了解过去做出决定的原因和方式。这对于稍后在项目中重新评估它们以及传播知识都很有用。

亚当给经理们提了几条建议,指的是人类心理。无论你是技术主管还是非技术经理,这些都是黄金。

首先,你永远不应该让人们觉得他们的贡献是可有可无的。不要取消他们在最后一刻一直在做的事情。这会导致动力的丧失。

此外,如果人们觉得团队的成功很少依赖于他们的实际努力,他们就会假装工作,期待别人来做这项工作。这就是社交闲逛。

因此,你永远不应该武断地设定目标或最后期限。一定要解释“为什么”。

最后,不要将行为准则度量作为个人绩效评估。如果你这样做,人们就会玩弄指标。这将破坏生产力和协作。因此,您将无法再使用这些指标。不聪明!

问题是,拥有专门的维护团队会带来一些不利于工作效率的问题:

就我个人而言,我通常建议让开发团队负责查找和修复bug。有专门的测试人员是可以的,但如果他们与开发人员密切合作就更好了。

还记得扩散分数吗?您也可以这样做,但是要计算添加的行数,而不是提交数。这样你就可以从每位作者的稿件中抽取1%的分成。

你不会想知道人们在哪里工作最多,而是想知道谁做出了最大贡献。

Git日志可以将其与--numstat一起使用。使用此功能,您可以绘制知识地图:

当您需要组建了解您需要重构的代码的最佳个人团队时,这会很有帮助。

您还可以在开发人员离开时确定知识转移的优先顺序。确定他们是公司的主要贡献者和对公司重要的部件。

这使您可以识别组织与您的体系结构的不一致之处。我们的想法是设置与团队一直在进行的工作相匹配的顶级边界。

此分析的限制取决于您的提交策略。如果您不能信任git提交作者,那么就不要使用它。例如,压缩合并策略会丢弃多个作者的贡献。在这种情况下,将重点放在“团队”视图上,或者将您的分析限制在技术方面(热点)。

如您所见,Adam Tornhill提供了一系列从大型代码库中获取宝贵信息的技术。

您也可以在体系结构级别应用这些技术。它适用于跨微服务的分布式系统:只需将每个分析的结果组合成一个更大的结果即可。

要在非常大的系统上掌握和采取具体行动,这是非常强大的。这是遗留代码的超级工具箱!

最后,您还可以使用这些指标来主动检测由于问题而导致的不断上升的技术债务。想象一下:如果一家公关被合并,你可以预见复杂性趋势的突然增加或热点的上升!这将是解决这个问题的最佳时机,因为它仍然是新鲜的和假设的。

是的你应该。这是值得的。我在这里只触及了皮毛。我相信这是非常有价值的知识。

如果你最感兴趣的是尝试一下,我不得不提一下:

Adam已经发布了一个开源工具来生成这里给出的大部分指标:code-maat。

所有这些概念都放在了Adam的产品中:CodeScene。它对开源是免费的,并给出了本书中描述的所有分析。

当我接近遗留代码库时,我使用这些技术来确定要做的最好的事情。如果你喜欢这篇摘要,你就会喜欢这本书。

订阅我的时事通讯,每周三直接在您的收件箱中接收我的传统代码提示和技巧。

由在加拿大蒙特利尔生活和工作的Nicolas Carlo撰写,🍁他创建了软件工匠蒙特利尔社区,该社区关心构建可维护的软件。

←返回主页