Shopify如何使用Strangler Fig模式重构遗留代码中上帝式大对象?- Adrianna Chang


大对象散布了代码的坏味道:随着职责和依赖的不断增长,它们变得越来越繁重,要定义它们究竟要负责什么变得更加困难。大对象更难重用,测试也较慢。更糟糕的是,它们花费了开发人员更多的时间和精力来理解,从而增加了引入错误的机会。未经检查的大对象冒着将代码库其余部分变成泥潭的风险,但是请不要担心!有一些策略可以减小大对象的大小和责任。
Shopify是一个多合一的商务平台,为全球超过一百万的商人提供支持。 Shopify的Ruby on Rails代码库中最关键的区域之一。Shop是一门繁重的大对象类,有超过3000行代码,其职责不胜枚举。当Shopify是一家具有较小代码库的较小公司时,Shop的目的职责很明确:它代表了托管在我们平台上的在线商店。今天,Shopify变得更加复杂,Shop模式的商业意图变得更加模糊。可以将其描述为“ 上帝对象”:一个知道很多并且做得太多的类。
我的团队Kernel Architecture Patterns负责在Shopify代码库中实施干净,高效,可扩展的体系结构。在过去的几年中,我们付出了巨大的努力来组建Shopify的整体代码库(请参阅解构整体),目的是在Shopify平台的不同域之间建立明确定义的边界。
在组件级别创建边界不仅重要,而且在组件内的对象之间建立边界也很重要。明确定义对象建模的业务子域非常重要。这样可以确保班级具有明确的界限和明确定义的职责集。
Shop的定义不清楚,语义边界也很弱。不幸的是,这使其成为增加新功能和复杂性的简单目标。作为倡导干净,建模良好的代码的倡导者,很明显,团队需要开始研究Shop模型,并将其某些业务流程移至更合适的对象或组件中。

使用ABC代码量度确定代码质量
找到起点的一种方法是使用代码度量工具。只要选择适合您的代码库,选择哪一个都不重要。我们的团队选择使用Flog,该代码根据代码每个区域中的分配,分支和调用的数量使用分数以了解代码质量遭受最大影响的地方。Shop类中发现了一个特别混乱的部分,其中包含与Shopify商店相关的众多“全局属性”。

用Strangler Fig模式进行重构
将Shop中的设置属性提取到更合适的组件中可带来许多好处,尤其是得到更好的凝聚力,以及无关代码与Shop模型的分离。重构工作是一项艰巨的任务,其中大多数设置在整个代码库的各个位置都被引用,通常是团队不熟悉的组件。我们知道我们可能会对这些设置应移至何处做出错误的假设。我们想要确保提取过程的布局合理,并且在我们对建模决策改变主意或犯错误的情况下,采取的任何步骤都易于逆转。确保Shopify不会停机的情况也是一个关键要求,并且一劳永逸地从旧系统迁移到全新系统似乎是灾难的根源。

什么是Strangler Fig模式
解决方案?马丁·福勒(Martin Fowler)的扼杀无花果图案。不要让这个名字吓到你!Strangler Fig模式为重构代码提供了一个增量,可靠的过程。它描述了一种方法,通过该方法,新系统可以在旧系统之上缓慢增长,直到旧系统被“勒死”并可以轻松删除为止。这种方法的优点在于,更改可以随时进行增量监控,并且发生意外中断的可能性非常低。在我们确信新系统可以按预期运行之前,旧系统将保持不变,然后删除所有旧代码就很简单了。

步骤:
步骤1:为需要提取的设置属性定义一个接口,该接口将依赖于现有的Shop对象,并将继续访问shop数据库表中的数据。

步骤2:将客户调用从旧系统改为调用新系统。

步骤3:如果需要编写新系统的新数据源

步骤4:在新模型中实现新的写入新数据源代码

步骤5:用旧数据回填新数据源

步骤6:更改新定义的接口中的方法以从新数据源中读取数据

步骤7:停止写入旧源代码并删除旧版代码

具体步骤点击标题见原文