调试代码遗留_如何征服遗留代码

调试代码遗留

At some point in your developer career, your boss will hand you a piece of legacy code — code that someone else wrote a long time ago. Your boss will tell you to learn this legacy code, fix it, and add new features to it.

在您的开发人员职业生涯的某个时刻,您的老板会把一段遗留代码交给您-别人很久以前编写的代码。 您的老板将告诉您学习此旧代码,对其进行修复并为其添加新功能。

I’ve been in this situation many times over the last two decades. I can help.

在过去的二十年中,我多次遇到这种情况。 我可以搭把手。

如何理解遗留代码 (How to understand legacy code)

If you’re lucky, you’ll have documentation, or at least in-line comments. Maybe one or two of the original authors will still even be around to help. But most of the time, you will not be so lucky.

如果幸运的话,您将获得文档或至少在线注释。 也许一两个原始作者甚至还会在身边提供帮助。 但是大多数时候,您不会很幸运。

Let’s talk about what you’re going to do in those unlucky cases.

让我们谈谈在那些不幸的情况下您将要做什么。

First, you need to be humble. Respect the code, and the developers who wrote it.

首先,你要谦虚。 尊重代码以及编写代码的开发人员。

It’s easy to look at work that came before you and decide it’s no good and that you can do better. This is the wrong attitude. It will lead you down a very dangerous path.

很容易看清您之前的工作,并认为这不好,您可以做得更好。 这是错误的态度。 它将带您走上非常危险的道路。

If you go down this dangerous path, you’ll start making changes before properly understanding the impact of those changes. You’ll “fix” things that aren’t broken, because they are written in a style that you don’t like, or are based on an older way of doing things. Ultimately, you’ll waste an incredible amount of time with this attitude.

如果您走这条危险的道路,您将开始进行更改,然后正确理解这些更改的影响。 您将“修复”未损坏的东西,因为它们以您不喜欢的样式编写,或者基于较旧的处理方式。 最终,您将以这种态度浪费大量的时间。

So stop. Take a step back and realize that everything in that codebase was done a certain way for a reason.

所以停止。 退后一步,意识到该代码库中的所有操作都是出于某种原因而做的。

Until you know the code forward and backward, you have to assume that there were good reasons for it to be written the way it is, and that you just haven’t figured them out yet.

在知道前后代码之前,您必须假设有充分的理由按原样编写它,而您还没有弄清楚它们。

This is a much more productive attitude, and it will save you from breaking everything, then just wanting to jump out of a window when you can’t put it back together quickly enough.

这是一种更有生产力的态度,它将使您免于破坏所有事情,而又只是想在无法足够快地将其放回原处时跳出窗口。

Don’t Humpty Dumpty your codebase.

不要笨拙笨拙的代码库。

The best way that I’ve found to learn a codebase is to start at the user interface level, then work my way back into the code.

我发现学习代码库的最好方法是从用户界面级别开始,然后再回到代码中。

Pick a single user flow, like logging in, placing an order, writing a review, or whatever is relevant to your particular application. Go through the flow as an end user. Then look at the code, starting with the user interface code — it should be the easiest to recognize — and follow each step on back, all the way to the database.

选择一个用户流程,例如登录,下订单,撰写评论或与您的特定应用程序相关的任何内容。 以最终用户身份进行操作。 然后查看代码,从用户界面代码开始-应该最容易识别它-并遵循每个步骤,一直到数据库。

As you go along, draw a sequence diagram to help illustrate what is happening. If you’re not sure what a sequence diagram is, or how to draw one, check out this free tutorial. If you don’t have a good tool for drawing UML, here’s a free one.

在进行过程中,请绘制顺序图以帮助说明正在发生的事情。 如果您不确定什么是序列图或如何绘制序列图, 请查看此免费教程。 如果您没有绘制UML的好工具, 这里有一个免费的工具

Once you’ve completed your first sequence diagram, using a local copy of the codebase that you can easily restore, start to make subtle changes to some of the components you’ve encountered. See if you can predict the effects of your changes on the application. This is a good way to test your understanding.

完成第一个序列图后,使用可以轻松恢复的代码库本地副本,开始对遇到的某些组件进行细微更改。 查看您是否可以预测更改对应用程序的影响。 这是检验您的理解的好方法。

Keep repeating this process, adding to your diagrams until you have a complete picture of the entire application (or at least all the parts you are responsible for).

继续重复此过程,添加到图表中,直到您对整个应用程序(或至少是您负责的所有部分)有完整的了解为止。

For bonus points, make sure you share your notes and diagrams. Put them in a highly visible place where the next developer who comes along can easily discover them. Don’t worry about making them perfect, or even pretty. Just do what you can. Every little bit helps.

对于奖励积分,请确保您共享笔记和图表。 将它们放置在一个高度可见的地方,下一个出现的开发人员可以轻松地发现它们。 不用担心使它们完美甚至漂亮。 尽你所能。 一点点帮助。

Overall, the most important thing is to be patient, and avoid beating yourself up. Code is a complex thing. Understanding legacy code takes time. Stay calm.

总的来说,最重要的是要有耐心,避免殴打自己。 代码是一件复杂的事情。 了解遗留代码需要花费时间。 保持冷静。

如何修复旧版代码 (How to fix legacy code)

The biggest challenge you’ll face when fixing legacy code is deciding how far to go with your fix. I strongly advise you to make the minimum viable change first. This means you should make the least disruptive change that completely fixes the problem before attempting to clean and refactor any code.

修复旧代码时,您将面临的最大挑战是确定修复的范围。 我强烈建议您先进行最小可行的更改 。 这意味着在尝试清除和重构任何代码之前,应进行最少破坏性的更改以完全解决问题。

This gives you an escape hatch. Worse case scenario, if you get pulled away to address some other priority — or if you’re on a tight deadline — at least you’ll have pulled together some working code that you can fall back on.

这给您一个逃生舱口。 更糟糕的情况是,如果您被迫解决其他一些优先事项-或者您的期限紧迫-至少您将整理一些可以依靠的工作代码。

Once you’ve gotten your code working, if you still have time left, you can start making small, incremental improvements.

一旦您的代码开始工作,如果还有时间,您可以开始进行小的,渐进的改进。

Martin Fowler has put together a catalog of refactorings which will give you a good idea of the types of changes you can make to incrementally improve a codebase. Check it out here. The idea is to always leave the code in better shape than it was when you found it.

Martin Fowler整理了一个重构目录,它将使您对可以逐步改进代码库的更改类型有一个很好的了解。 在这里查看 。 这样做的目的是使代码始终保持比发现时更好的状态。

Sometimes, you’ll encounter a bug that is actually the result of a structural defect. These bugs can’t be fixed by a simple change to some conditional logic. They require more invasive changes.

有时,您会遇到实际上是结构缺陷导致的错误。 这些错误无法通过对某些条件逻辑的简单更改来解决。 他们需要更具侵略性的变化。

This is where things get hairy. You have to be brutally honest with yourself about what the minimum viable change is. Every fiber of your being will want to pull the code apart and re-write the whole thing. Don’t do it!

这是毛茸茸的地方。 您必须对自己的残酷诚实做些最小的改变。 您的每一根纤维都希望将代码拆开,然后重新编写整个内容。 别做!

Stick to a quick fix, followed by an incremental improvement that refactors it and cleans it up as much as time permits. Your goal is just to make the code a little better every time. The longer you maintain the codebase, the better it will get.

坚持快速修复,然后进行逐步改进,以对其进行重构并在时间允许的范围内对其进行清理。 您的目标只是每次都使代码更好一点。 您维护代码库的时间越长,它将越好。

To truly make this approach work, make sure you’re always padding your estimates to allow time for a bit of refactoring.

为了使这种方法真正起作用,请确保始终填充估算值,以便有时间进行重构。

Sometimes, the structural defects are so bad that a strategy of forever patching just won’t work. This situation is actually much more rare than you might think.

有时,结构缺陷是如此严重,以至于永远无法修补的策略将无法工作。 这种情况实际上比您想像的要罕见得多。

Again, you have to be brutally honest with yourself about the cost/benefit of a rewrite or redesign. You need to accept that, ultimately, this will be a business decision and not a technical one.

同样,对于重写或重新设计的成本/收益,您必须对自己残酷地诚实。 您需要接受的是,最终这将是业务决策,而不是技术决策。

Prepare to state your case in business terms. What will it cost to do a major restructuring of the code? What are the real business risks of not doing it? If you have a solid case, you will eventually be heard. Don’t be surprised if it takes a few more cycles of patching first, though.

准备用商业术语陈述您的情况。 进行代码的重大重组将需要多少费用? 不这样做的真正商业风险是什么? 如果您有充分的理由,您最终将被听到。 不过,如果要先进行一些修补,则不要感到惊讶。

Remember: if you are doing a major overhaul, first make sure there’s support for the change and a reasonable budget to go along with it. Don’t try to fly under the radar with this. Unless, of course, you relish awkward conversations with management when you start breaking things and missing deadlines.

切记:如果要进行大修,请首先确保对更改有支持,并有合理的预算。 不要试图以此躲藏在地下。 当然,除非您开始破坏事务并错过最后期限时与管理人员进行尴尬的交谈。

如何向旧代码添加新功能 (How to add new features to legacy code)

Finally, you will eventually be called upon to add features to legacy code. At this point, you have an important decision to make. Do you “go with the flow” of the current codebase, or take things in a new direction?

最后,最终将要求您向旧代码添加功能。 在这一点上,您需要做出重要决定。 您是“顺应当前代码库的流程”,还是朝着新的方向发展?

Again, I advise you to be brutally honest in your evaluation. Would continuing to follow the patterns and practices evident in the existing codebase make it worse, or pile onto an existing problem?

再次,我建议您在评估中要诚实一些。 继续遵循现有代码库中显而易见的模式和实践会使其变得更糟,还是堆积在现有问题上?

Most of the time, you’ll want to keep things stable. Just make incremental additions using the existing patterns and practices of the code. Re-use existing elements. Make the least disruptive changes possible, while making small, incremental improvements by cleaning and refactoring.

大多数时候,您会希望保持稳定。 只需使用代码的现有模式和实践进行增量添加即可。 重用现有元素。 进行尽可能小的破坏性更改,同时通过清理和重构进行较小的增量改进。

If you believe that a new direction is absolutely necessary, then you’ll need to find a way to isolate your changes and couple them as loosely as possible to the existing codebase.

如果您认为绝对有必要提供一个新的方向,那么您将需要找到一种方法来隔离您的更改并将它们尽可能宽松地耦合到现有代码库。

Try carving out the new feature as a separate project. You can then expose an API that lets the legacy code plug into your new code. This makes it so that your new code and the old legacy code don’t need to know much about each other.

尝试将新功能划分为一个单独的项目。 然后,您可以公开一个API,该API可以将旧代码插入新代码中。 这样一来,您的新代码和旧的遗留代码就不需要彼此了解很多。

This starts to get a bit tricky when you need to use functionality from the legacy code in order to implement the new feature. The best way to isolate the old code from the new code is to use the Adapter Pattern.

当您需要使用旧版代码中的功能以实现新功能时,这将变得有些棘手。 将旧代码与新代码隔离的最佳方法是使用适配器模式。

DO Factory has a good explanation of the Adapter Pattern:

DO Factory对适配器模式有很好的解释:

“The Adapter pattern translates one interface (an object’s properties and methods) to another. Adapters allow programming components to work together that otherwise wouldn’t because of mismatched interfaces. The Adapter pattern is also referred to as the Wrapper Pattern.
适配器模式将一个接口(对象的属性和方法)转换为另一个。 适配器允许编程组件协同工作,否则将由于接口不匹配而无法协同工作。 适配器模式也称为包装器模式。
One scenario where Adapters are commonly used is when new components need to be integrated and work together with existing components in the application.
通常需要使用适配器的一种情况是需要集成新组件并与应用程序中的现有组件一起使用。
Another scenario is refactoring in which parts of the program are rewritten with an improved interface, but the old code still expects the original interface.”
另一个场景是重构,其中使用改进的界面重写程序的某些部分,但是旧代码仍然需要原始界面。”

Here are some links to explanations and examples in various languages.

以下是各种语言的解释和示例的链接。

重要要点 (Key takeaways)

In summary, here are the key points that will help you tackle and ultimately conquer any codebase:

总之,以下是可以帮助您解决并最终征服任何代码库的关键点:

  1. Never judge legacy code or change it until you’ve taken the time to fully understand it.

    在花时间完全理解旧代码之前,请不要对其进行判断或更改。
  2. Sequence diagrams are your friend.

    顺序图是您的朋友。
  3. Prefer small, incremental improvements over wholesale re-writes or changes.

    相对于整体重写或更改,建议进行较小的增量改进。
  4. Each change should attempt to leave the code a little better off than it was when you found it.

    每次更改都应尝试使代码保持比发现时更好的状态。
  5. If you need to make big changes, make a business case and get approval first.

    如果您需要进行重大更改,请制定业务案例并首先获得批准。
  6. When adding new features, try to “go with the flow.”

    添加新功能时,请尝试“顺其自然”。
  7. If you need to take the code in a new direction, isolate your changes and use the Adapter Pattern to integrate.

    如果您需要将代码带入新的方向,请隔离您的更改并使用适配器模式进行集成。

Hopefully you found this article useful. My mission is to help as many developers as I can. Please ❤ recommend ❤ this story using the green heart below to help spread the word.

希望您发现本文有用。 我的任务是尽我所能来帮助开发人员。 请❤建议❤这个故事,请使用下面的绿色心形帮助传播。

Want to code better? Join thousands of developers who receive valuable articles and information like this from me every week for free. Just click here.

想要更好地编码? 加入成千上万的开发人员,这些开发人员每周免费获得我如此有价值的文章和信息。 只需单击此处。

翻译自: https://www.freecodecamp.org/news/conquer-legacy-code-f9e23a6ab758/

调试代码遗留

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值