DEV Community

Refactoring Legacy Monoliths - Part 1: First Steps

James Hickey on September 07, 2018

Originally published on my blog. Where do you even begin when considering "fixing" or refactoring legacy monoliths? What Is A Legacy Mon...
Collapse
 
pim profile image
Pim

Great post! I'm embarrassed to admit that I only recently started implementing unit testing in a serious way. Two things became very apparent to me, and very quickly. Despite thinking I wrote "clean" software, it was in fact polluted with things like SRP violations and rigid dependencies. Having to implement unit testing, not only made my code better but actually made me like coding all over. Equipping me with a new set of glasses to peer through. Oddly enough the small bit of functional programming I dabbled in helped a lot, which I've learnt I do not like at all, it just feels clunky to me.

As a total side note, Coravel looks freaking AWESOME. I haven't had a chance to use it yet. But I will most certainly be doing that on Monday. Are you accepting contributors? Pull requests?

Collapse
 
jamesmh profile image
James Hickey • Edited

Thanks for feedback! I agree 100% - I'll be covering the issue of dependencies in a future article. One of the main benefits of functional programming is the idea of pure functions - functions that get an input and give an output and don't change the outside world (no side-effects). If you build your objects/classes this way you get the same benefits.

I'm taking contributors for Coravel - mostly for smaller issues right now. If you have any ideas then feel free to create an issue and we can go from there ;) Thanks for the comment Pim!

Collapse
 
aleksikauppila profile image
Aleksi Kauppila

Good post! Separation of business domain from presentation and persistence concerns is essential for long running development. In legacy systems these can however be completely mixed and separation will constitute to a full rewrite.

Collapse
 
bosepchuk profile image
Blaine Osepchuk • Edited

Great post, James.

I've gone through this a couple of times and in my experience there are a few steps that help "prepare the code" for the changes you are suggesting such as:

  • Making sure the entire project is under modern version control
  • Running the entire project through a code formatter
  • Delete dead and commented-out code
  • Delete unused features
  • Run a bunch of static analysis tools on the code to get a feel for the magnitude of the problem
  • Run the existing tests with coverage and see where that's at
  • Identify and fix any emergency issues (update libraries to fix security vulnerabilities, or update the code to run on a newer version of the language if the currently used version is no longer supported, fix obvious and serious security vulnerabilities in your code)
  • Flag suspicious code with TODO or FIXME contents for further inspection at a future date

If you do these steps, I guarantee you'll find things that shock and surprise you and that you'll be able to delete quite a bit of code (about 10% of the project in my limited experience).

There's a really good book called Modernizing Legacy Applications in PHP, which I highly recommend if PHP is your language.

After that you have some options. I'm not exactly sure where James is going to go next but I'm sure he'll have good advice.

We use tons of the "extract method" and "extract class" refactorings to break out pieces of testable code from dependencies using the humble object pattern. We also break dependencies by using dependency injection. Classes and methods in legacy code are often too big and are doing too many things. So our first priority is usually to break things up and test what we can.

But there are a number of reasonable ways forward from here depending on your priorities.

Collapse
 
jamesmh profile image
James Hickey

Love it! Should turn this into a blog post altogether ;)

I'll have to repeat much of what you said as the series continues. I think one of the main issues that need to be tackled is the direction of dependencies and (as you mentioned in much more detail) how to break things apart in a way that will isolate dependencies. This leads to being able to test individual parts in an isolated fashion.

But I'm just repeating what you've said :)

I appreciate the additions - I'm sure this will be super helpful to anyone who's interested in this topic.

Collapse
 
fgiraldi profile image
fgiraldi

Nice post. I wish I would have one of this readings many years ago. I've been developing in PHP using what I learned in college since 2001 (I'm 39 years old) and back then my only tools where the PHP documentation and a text editor. All I could wrote was monolithic code and, embarrasingly, I´ve been doing that for the last 17 years.
As of today, I know what a framework is, what the MVC stack means and their benefits. I´ve changed mi mind thanks to some of my frineds who showed me a better way of coding and now I´m on a new train with new (better) concepts and a refreshed mind about how to make my daily job, which turns out to be my passion, so I feel again I´m just enjoying my hobby again.
Thanks for the post.

Collapse
 
jamesmh profile image
James Hickey

Thanks for the comment! Drop me a message if you ever have questions etc. :)