我目前在一段代码中,其中逻辑和数据访问都存在于GUI类中。显然,我想改善这种情况。大规模重构策略
目前的结构基本上是:
- 大泥球
的最终目标是实现DDD状结构:
- DAL
- 领域模型
- 服务层
- 演示模型
- GUI
那么,你会如何进攻的问题?
- 大爆炸
- 定义最终状态的结构,推动代码到它的最终归属。
- 分而治之
- 尝试在泥中分离的大球,以两片。重复,直到完成...
- 绞杀
我目前在一段代码中,其中逻辑和数据访问都存在于GUI类中。显然,我想改善这种情况。大规模重构策略
目前的结构基本上是:
的最终目标是实现DDD状结构:
那么,你会如何进攻的问题?
永远不要尝试“大爆炸”。它几乎总是吹在你的脸上,因为当一切都失败时,这是一种高风险,绝望的措施。
分而治之:这个效果很好......如果你的世界只有两面。在真正的软件中,你必须同时征服这么多的战线,你几乎不能承受黑白的幻想。
我想我在职业生涯中大部分时间都在使用“Strangling”这样的东西:逐渐将不好的旧代码转化为闪亮的新代码。这里是我的食谱:
从某处开始,它在哪里并不重要。编写几个单元测试,看看代码如何表现。了解它多久做一次你认为它的作用,以及它多长时间不这样做。使用您的IDE重构代码,以便测试它。
第一天过后,猜猜你是否已经开始在正确的地方将这个怪物分开。如果是这样,继续。如果没有,找到一个新的地方,并重新开始。
这个策略的优点:它的工作步骤很小,所以风险可以控制在一定的范围内,如果有事情发生,如果必须在上周的代码中。
缺点:需要花费很多时间,你会感到沮丧,因为通常情况下,进度会显得非常缓慢,直到“结”突然出现,突然间,所有东西都像魔法一样开始落伍。
是完全重写的选项?根据我的经验,从头开始重写通常比试图清理现有的混乱更有效。你冷漠仍然保留现有代码的一部分,但在一个新的情况下。如果有的话,gui和数据库也是一样的。从头开始重写,随身携带你可以使用的东西。
取决于您是否必须始终处于工作状态,以便您可以在需要时进行错误修复和部署,然后Devide and Conquer将是一个很好的解决方案。如果您可以在维护旧代码的同时开发新代码(并且将代码修复应用到代码库中),那么重写可能是更好的解决方案。
我从来没有听说过'Strangler Application'这个词 - 我喜欢它。在可能的情况下,这总是一个很好的方法,它可以最大限度地降低风险,并且非常务实,一块一块削减大型建筑物。
根据我的经验,哪里工作不正常是需要马上进行合理的重大更改 - 需要一点重构(或大量黑客攻击)的更改。在那种情况下,我经常发现我需要做的改变是在大泥球的中心,没有其他选择,但是变得肮脏 - 即使是标准维护或微小的增强改变也是可怕的,而且主要的重构是最好的选择。
对于这些情况,我会用分而治之 - 我一直追求的第一个目标就是可测试性,一旦你让所有其余的都变得容易了。事实上,这通常是我从重大泥土中重构的主要驱动因素之一 - 这类代码通常几乎不可测试,希望有示例UI输入和输出,但有时甚至缺少这些代码。
因此,当遇到代码将所有内容都集中到UI中的情况下,我通常首先将分离的功能单元分解为类和方法,然后将这些代码部分推入域或服务层。一点点做,大大减少了打破某些东西的机会,并且可以更容易地指出事情发生错误时破坏代码的位置。
在每次更改结束时运行任何可用的测试用例,并确保您仍然满足某种基准。
如果你随时编写好的单元测试,你可以开始减小问题的规模,我发现采用扼杀者方法很快就会变得实用 - 通过合适的单元测试或者至少允许正确的框架允许体面的单元测试的写作变得更加实用,逐渐取代部分功能。
如果通过重构,你的意思是在不修改功能的情况下改进代码,我首先创建一个自动化的回归测试基线。有很多工具可以帮助解决这个问题。我使用TestComlete,虽然有很好的便宜替代品。
建立了一个回归测试基线后,我个人会随着分而治之,因为根据我的经验,它最有可能成功。一旦你有了一个测试基准,那么你选择的方法就更少了。
从一个干净的新架构开始,将代码中的旧代码逐块移动到这个新的架构中,并重构它以适应新的拱架将是一个不错的选择。移动功能时我认为采取自下而上的方法会很好。
对我来说这取决于情况。
如果这是一个非常小的项目,我会试图从零开始重写它......但是你并不经常拥有这种奢侈品。
如果不这样做,我会一块一块地去打碎它。我会编写单元测试来验证现有的功能,并慢慢地使用TDD将代码转换为一个优雅且设计良好的系统。取决于这个过程需要多长时间,它可能会开始看起来像你上面提到的StranglerApplication。
BigBang风险很大,因为您没有简单的方法来验证更新后的系统是否与旧版系统执行相同的操作。
分而治之风险比BigBang风险小...但如果它的系统足够大,它可能会像BigBang一样存在问题。
我偶然发现了“天皇法”,它似乎很有希望攻击这种性质的问题。
http://mikadomethod.wordpress.com/
还有来自Øredev一谈日本天皇方法2010年
http://oredev.org/2010/sessions/large-scale-refactorings-using-the-mikado-method
大爆炸/大重新设计/重写SW ......或任何其他名称将不适合生活SW。 原因是:
你仍然需要支持(可能)你有同样的资源,现有的SW。
您可能没有重写的要求。您的旧代码具有嵌入其中的所有要求。您的工程师都不知道所有的软件领域和所有要求。
重写需要时间。在这段时间结束时,你会发现现有的软件已经改变,以支持在这段时间内需要的东西。 你的新SW实际上是从原来的分裂和合并将需要(这也将需要时间)。