大规模重构策略

发布于 2024-07-09 18:14:09 字数 1447 浏览 6 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

傾城如夢未必闌珊 2024-07-16 18:14:09

永远不要尝试“大爆炸”。 它几乎总是打在你脸上,因为当其他一切都失败时,这是一种高风险、绝望的措施。

分而治之:如果你的世界只有两个方面,这很有效。 在真正的软件中,你必须同时征服如此多的前沿,你很少能够生活在黑白幻想中。

我想我在职业生涯的大部分时间里都在使用类似“绞杀”的东西:逐渐将糟糕的旧代码变成闪亮的新代码。 这是我的秘诀:

从某个地方开始,从哪里开始并不重要。 编写一些单元测试来查看代码的实际行为。 找出它执行您所认为的操作的频率以及不执行您认为的操作的频率。 使用 IDE 重构代码以便进行测试。

第一天之后,猜测一下您是否从正确的位置开始分解这个怪物。 如果是这样,请继续。 如果没有,就找一个新的地方并重新开始。

这种策略的优点:它分小步进行,因此可以控制风险,如果出现问题,则必须在您上周处理的代码中。

缺点:这需要花费很多时间,而且你会感到沮丧,因为通常情况下,进展看起来很慢,直到“结”突然弹出,一切都开始像魔法一样各就各位。

Never attempt "Big Bang". It almost always blows in your face, since it's a high-risk, desperate measure when everything else has failed.

Divide and conquer: This works well ... if your world has only two sides. In real software, you have to conquer so many fronts at the same time, you can rarely afford to live in a black-white fantasy.

I guess I've been using something like "Strangling" for most of my career: Gradually morphing bad old code into shiny new code. Here is my recipe:

Start somewhere, it doesn't really matter where. Write a few unit tests to see how to the code really behaves. Find out how often it does what you think it does and how often it doesn't. Use your IDE to refactor the code so you can test it.

After the first day, make a guess whether you've started at the right place to take this monster apart. If so, go on. If not, find a new place and start over.

Advantages of this strategy: It works in small steps, so the risk can be kept in check and if something breaks, if has to be in the code you've been working on last week.

Disadvantage: It takes a whole lot of time and you will feel frustrated because often, progress will just seem so slow until the "knot" pops and suddenly, everything starts fall into place as if by magic.

手长情犹 2024-07-16 18:14:09

我从未听说过“Strangler 应用程序”这个词——我喜欢它。 在可能的情况下,这始终是一个好方法,它确实可以最大限度地降低风险,而且非常务实,一点一点地削弱这座大厦。

根据我的经验,这不起作用的地方是需要立即进行相当重大的更改 - 需要进行一些重构(或大量黑客攻击)的更改。 在这种情况下,我经常发现我需要做的改变就在大泥球的中心,除了弄脏之外别无选择 - 即使应该是标准维护或微小的增强改变也是可怕的和a主要重构是最好的选择。

对于这些情况,我会采用分而治之的方法 - 我始终追求的第一个目标是可测试性,一旦实现了这一目标,其余的一切都会变得容易得多。 事实上,这通常是我从大泥球中重构出来的主要驱动力之一——这类代码通常几乎无法测试,希望有示例 UI 输入和输出,但有时甚至缺少这些。

因此,当面对所有内容都集中到 UI 中的代码时,我通常首先将离散的功能单元分解为类和方法,然后将这些部分的代码推送到域或服务层中。 一点一点地做可以大大减少破坏某些东西的机会,并且在出现问题时更容易查明破坏代码的位置。

在每次更改结束时运行可用的任何测试用例,并确保您仍然满足某种基线。

如果你随时编写良好的单元测试,你就可以开始缩小问题的规模,而且我发现采用绞杀方法很快就变得切实可行——使用像样的单元测试或至少有正确的框架来允许编写像样的单元测试。单元测试逐渐替换部分功能变得更加实用。

I'd never heard of the term 'Strangler Application' - I like it. Where possible this would always be a good approach, it certainly minimises risk and is quite pragmatic, chipping away at the big edifice piece by piece.

Where that doesn't work in my experience is where reasonably significant changes are needed right away - changes that will require a bit of refactoring (or a lot of hacking). In that situation I've often found the changes I needed to do were right at the heart of the big ball of mud and there was no option but getting dirty - even what should have been standard maintenance or minor enhancement changes were just horrible and a major refactor was the best option.

For those cases, I'd go with divide and conquer - the first goal I always aim for is testability, once you have that all the rest is so much easier. In fact, that is often one of the main drivers I have for refactoring away from the big ball of mud – that sort of code is often very nearly un-testable, hopefully there are example UI inputs and outputs, but sometimes even that is missing.

So when faced with code where everything is lumped into the UI I usually start by factoring discrete units of functionality into classes and methods, then pushing those parts of code down into a domain or service layer. Doing it bit by bit greatly reduces the chance of breaking something and makes it easier to pin-point where the breaking code was when things do go wrong.

Run whatever test cases you have available at the end of every change and make sure you are still meeting some sort of baseline.

If you write good unit tests as you go you can start reducing the scale of the problem and I've found that it soon becomes practical to take the strangler approach - with decent unit tests or at least the right framework to allow the writing of decent unit tests it becomes much more practical to gradually replace parts of functionality.

傲世九天 2024-07-16 18:14:09

我偶然发现了“天皇方法”,它似乎有望解决此类问题。

http://mikadomethod.wordpress.com/

Øredev 2010 也有一篇关于 Mikado 方法的讨论。

< a href="http://oredev.org/2010/sessions/large-scale-refactorings-using-the-mikado-method" rel="nofollow">http://oredev.org/2010/sessions/large-使用 mikado 方法进行规模重构

I stumbled upon "the Mikado Method" that seems promising for attacking problems of this nature.

http://mikadomethod.wordpress.com/

There is also a talk about the Mikado Method from Øredev 2010.

http://oredev.org/2010/sessions/large-scale-refactorings-using-the-mikado-method

白云悠悠 2024-07-16 18:14:09

取决于你是否必须始终保持工作状态,以便可以在需要时修复错误并进行部署,那么分离和征服将是一个很好的解决方案。 如果您可以维护旧代码,同时编写新代码(并且有纪律对两个代码库应用错误修复),那么重写可能是更好的解决方案。

Depends on whether you have to have always a working state, so that you can bug-fix and deploy whenever neccassary, then Devide and Conquer would be a good solution. If you can maintain the old code, while working on a new one (and have the disciplin to apply bug-fixes to both code-bases) a re-write may be a better solution.

如果重构是指在不修改功能的情况下改进代码,那么我将从创建自动回归测试基线开始。 有很多工具可以帮助解决这个问题。 我使用 TestComlete 尽管有很好的廉价替代品。

建立回归测试基线后,我个人会采用分而治之的方法,因为根据我的经验,这是最有可能成功的。 一旦有了测试基线,选择哪种方法就不那么重要了。

If by refactoring, you mean improving the code without modifying the functionality, I'd start by creating an automated regression testing base line. There are plenty of tools out there to help with this. I use TestComlete though there are good cheap alternatives.

Having established a regression test baseline, personally I would then go with divide and conquer, as it in my experience it is the most likely to succeed. Once you have a testing baseline, it matters less which approach you choose.

蛮可爱 2024-07-16 18:14:09

对我来说这取决于具体情况。

如果这是一个非常小的项目,我会很想从头开始重写它......但是您通常不会有这种奢侈。

如果做不到这一点,我就会去一点一点地削减它。 我会编写单元测试来验证现有功能,并慢慢使用 TDD 将代码转换为优雅且设计良好的系统。 根据这个过程需要多长时间,它可能会开始看起来像您上面提到的 StranglerApplication。

BigBang 的风险非常大,因为您没有简单的方法来验证更新后的系统是否与旧系统执行相同的操作。

分而治之的风险比 BigBang 小……但如果它是一个足够大的系统,它最终可能会像 BigBang 一样出现问题。

For me it depends on the situation.

If it is a very small project I'd be tempted to just rewrite it from scratch...however you don't often have that luxury.

Failing that, I'd go for chipping away at it piece by piece. I'd write unit tests to verify the existing functionality and slowly use TDD to transform the code into an elegant and well designed system. Depending on how long this process is going to take it will probably start to look like the StranglerApplication you mentioned above.

BigBang is very risky as you have no easy way of verifying that the updated system does the same thing as the old one.

Divide and Conquer is less risky than BigBang...but if its a large enough system it can wind up being just as problematic as BigBang.

吾家有女初长成 2024-07-16 18:14:09

大爆炸/大重新设计/重写软件......或任何其他名称将不适用于活着的软件。
原因是:

  • 您仍然需要使用(可能)您拥有的相同资源来支持现有软件。

  • 您可能不具备重写的要求。 您的旧代码已嵌入其中的所有要求。 你们的工程师都不知道所有的软件领域和所有的要求。

  • 重写需要时间。 在此时间结束时,您会发现现有的软件已更改以支持这段时间所需的内容。
    您的新软件实际上是从原始软件中分离出来的,并且需要合并(这也需要时间)。

Big bang / Big re-design / rewriting the SW ... or whatever other names will not work for a living SW.
The reasons are:

  • You still need to support the existing SW with (probably) the same resources you have.

  • You probably do not have the requirements for rewriting. Your old code has all the requirements embedded inside it. None of your engineers know all the SW domains and all the requirements.

  • Rewriting will take time. At the end of this time you will find that the existing SW has changed to support things that were required during this time.
    your new SW actually split from the original and merge will be needed (which will also take time).

单身狗的梦 2024-07-16 18:14:09

是否可以选择完全重写? 根据我的经验,从头开始重写通常比试图清理现有的混乱更有效。 您仍然保留部分现有代码,但在新的上下文中。 如果您有图形用户界面和数据库,情况也是如此。 从头开始重写并随身携带您可以使用的内容。

Is a total rewrite an option? In my experience rewriting from scratch can often be more efficient than trying to clean up the existing mess. You cold still keep parts of the existing code but in a new context. And the same goes for the gui and the database if you have one. Rewrite from scratch and take with you what you can use.

驱逐舰岛风号 2024-07-16 18:14:09

从一个干净的新架构开始,将旧的代码一段一段地移动到这个新架构中,并重构它以适应新的架构将是一个不错的选择。 我认为在移动功能时采用自下而上的方法会很好。

Starting with a clean new architecture and moving the old peices of code into this new architecture piece by piece and refactoring it to suit the new arch would be a good option. I think a bottom up approach when moving the functions would be good.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文