How to fix that old software.

Have you ever rewritten code from another developer? It is an exhausting and painfully frustrating battle. If you do everything right, then it looks like nothing changed. It usually involved lots of wandering around the code only to find that they are tracking state in the an obscure variable. At some point you just want to throw the whole thing out. 

DON’T DO IT!

My friend Kevin approaches software development unlike any other developer I have ever met. He does an amazing job rewriting old code and repairing old systems. I took it upon myself to study what he is doing because it is so very powerful and useful. What I realized is that it is a repeatable set of steps. Like a martial art kata. If you can master this way of thinking you can make incremental improvements on your software one test at a time. This allows you to incrementally make it a well tested, easy to reason about system, that is much more maintainable for the life of the software.

Kevin’s Refactoring Kata

Step 1: Look at the system or component as a whole and regroup the functionality.

Step 2: Let each of your new components do one thing and do it well.

Step 3: Write your tests first describing all the behaviors you know it will need.

Step 4: Write your code new and use the old code as a reference.

Step 5: Get all the test to work.

Step 6: Swap it out.

 

Now to elaborate

Step 1: Look at the system or component as a whole and regroup the functionality.

First identify what the code is doing and what the behavior is suppose to be. This can be tricky because software sometimes has become entwined with other components and behaviors. For instance, they might be using a column in a database to represent state that triggers something else in the system. The advice here is to keep getting smaller until you can actually identify a component. Start with that. If you are unsure, start somewhere else. With every tests it will become easier to sort out what is going on.

Step 2: Let each of your new components do one thing and do it well.

This is based on the S “Single responsibility” in SOLID. It helps to start by naming the new component better. Try to name it things like CheckinService or CheckInController. Not something so vague like UserManager. In fact, try never to name it “Manager” or “Util”. These tend to create software with overloaded functionality. It’s like the box in the garage called “Misc” which is full of all the random bits that you don’t know where else to put them. Once you have your name then it is easier to make sure you know what it does.

 Step 3: Write your tests first describing all the behaviors you know it will need.

In this step just think through what this component does. Does it add more users? Does it make sure that users have a special permission? What does it do if given a bad user? Just list all of these as if they are tests. Make sure these test don’t cause it to fail but simply list the behaviors you are expecting.

 Step 4: Write your code new and use the old code as a reference.

Make your new component alongside the old chunk of code. Then start with the first test and write it. It should fail!  Now go add some code to the new component until it doesn’t. Keep going though this loop adding tests and behaviors until this one component is well defined. When you get stuck you can use the old code as a reference to understand what the previous system did. 

Step 5: Get all the test to work

Don’t stop until you have finished the tests. What is great about this approach is that you don't have to do it all at once. If you have to take a break leave yourself a broken test so you know where to start when you get back to it. You should be able to get a test created and solved in a fairly routine way. Each one gets you closer to being done. If you find yourself feeling discouraged, just run your tests again and you can see how far you have come. It’s small but it does make you realize that you are chipping away at it.

Step 6: Swap it out

Now you get to switch your code in for the old code. After you have proven you that the system as a whole works, you get to DELETE THE OLD CODE. That really is the best part.

 

To conclude

I know this seems obvious when you write it this way but it is so very very easy to find yourself on an endless adventure unraveling other developers super clever ideas.  They took shortcuts, they wanted to show how brilliant they are, they didn’t make it easy to understand. By following through on these steps you are on your way to a much easier to maintain system.