So i recently inherited some legacy code.
Its actually not to bad. Just a few thousand locs which are mostly stretched across a handfull of functions lmao (800lines per function yay).

So the main thing i wana ask. Does someone here know of good techniques to gradually reimplement all of this.
Since im not gonna apply bandaids to this mess anymore than is needed.

Unfortunately this is a very important system and it only runs on production xD.

Idealy i would somehow be able to duplicate the tcp traffic to the reimplementation but that doesnt seem feasible.

Also what the individual modules classes and so on do wa snever documented and no one even knows how or why certain things even exist.

If anyone has any idea of what i can do. Apart from hoping to god i dont miss any weird quirky edge cases. Do let me know

  • 0
    If there's a better way than line-by-line, I still haven't learned it.

    I ported like 10K lines of code last week this way. Sucks, and MAYBE there is some cross-compiler that could automate it... but then you'd just have a cross-compiled piece of shit, when the point of the refactor was to create better code on a better platform.

    I think most of the point of a port/refactor like this is to have a set of experienced eyes look over it for shitty code, port where they can, and rewrite where they can't.
  • 1
    @HiFiWiFiSciFi kinda yes. The main point of this refactor is to find out what the fuck this thing does. And get it to a maintainable state. Eg documented as to what the components do and behaviour explained and all.
    Plus getting it lifted from the old java 8 env to a new shiny spring one and java 11 which we currently use :)
  • 2
    Working Effectively with Legacy Code by Michael Feathers is pretty much the Bible for this, but there are no easy answers, or short cuts. Hopefully your boss knows it will take a lot of effort over a long period of time.

  • 4
    1. Write comprehensive tests. Unit tests won't be possible since there's no way this code was designed in a way that it can be sanely unit tested, so you'll need to just use integration tests on the network layer instead. Pick corner cases, pick a bunch of general cases, and make sure you've covered everything you can think of. This step will take a while just by itself - don't skimp on it.

    2. Delete or alter a meaningful chunk of code. Check at least one of your tests fail with each thing you change. If it fails, make sure you understand what that code does, and how it affects the test. If not, make sure you understand what that code does and write a test that covers it. Repeat until you've covered everything.
  • 3
    3. Make changes in incremental, small commits, checking all your tests pass at each stage. If you find a new case you need to test, then go back to the original code, write the test, ensure it passes. Switch the relevant piece of legacy code out, ensure it fails (to check the test works.) Switch to your current code, and if it fails, you can then git bisect your changes to find the specific change you introduced that caused the failure, and fix it accordingly.

    4. As you make changes, ensure that you're rewriting it to use unit tests, good practices, etc. - make sure your unit tests are covering everything, so the integration tests won't be required to test each code path when you're done.

    5. When you're done, ideally parallel run it with production and compare results. If you can't parallel run it, ideally grab a full weeks data and run that through the system after the fact, comparing outcomes between the two.
  • 3
    6. If anything differs at this point, write another integration test, rinse and repeat until you've covered all cases and you're confident it works.

    Yes, this is a more time consuming process than the typical "rewrite it, shove it in and hope for the best" scenario that often happens. But having done this to a fair few legacy apps in the past, it generally works very well, and is the gold standard I use when converting critical production infrastructure.
  • 1
    @AlmondSauce sounds like a plan. Main problem problem in my case is. Ive got no clue what these test should look like.
    No one can tell me what it does. Only feedback we get is when the enduser cant do anything anymore.
    Its a very convoluted system which is from the 2000s xD.

    But yeah its gonna be fun trying to make sense of all those edge cases which it has hundreds of xD
Add Comment