When you inherit difficult code it can take weeks to become productive. Having the right tools for the job and knowing how to use them makes a huge difference. These videos show you how.
Note: this post originally appeared here https://www.praqma.com/stories/advanced-testing-refactoring-techniques/
Sometimes you donโt know what a piece of code is supposed to do, but you do know that people are using it in production, and that it in some sense โworksโ. One approach I often use in this situation is Approval testing. It can get you test coverage quickly without having to understand the code.
Since you donโt know what the code is supposed to do, you canโt define in advance what results you expect. But, what you can do is run the code, accept whatever it does as โcorrectโ, then invent scenarios that will exercise all the code branches. Iโve made a video of me doing just this on some rather hairy legacy code – The Gilded Rose Refactoring Kata. With the right tools the tests fall into place relatively easily.
Iโd like to credit Llewellyn Falco who showed me this way to solve this exercise.
I recorded a screencast in three parts. This is the first part.
Part 1: Introducing the Gilded Rose kata and writing test cases using Approval Tests
About the Gilded Rose code
One of the exercises Iโve used for years to help programmers improve their skills is the Gilded Rose Kata. Itโs a refactoring kata – the code needs cleaning up and tests adding so you can build a new feature. That is a realistic scenario that programmers often face in everyday work, but this exercise adds a fantasy twist. The code you have to work with keeps track of various magical items stocked at the Gilded Rose establishment. The new feature concerns support for โConjuredโ items that have slightly different magical properties from the other items. The scenario is just weird enough to be fun and just realistic enough to be a useful exercise.
I didnโt design the kata originally, that was Terry Hughes. I spruced up the code a little to make it a better exercise and added some extra instructions to get you going. I also translated the starting code into a few different programming languages and put it up on GitHub. In the 5 years since then I have been delighted to see how popular itโs become. Iโve had over 50 contributors chip in with various translations and improvements, and at least 800 people have forked the project and presumably had a go at the refactoring.
I think the appeal of the exercise is partly the wacky scenario it throws you into, and partly how utterly terrible the code is at the start. If you do the refactoring well it actually looks really neat at the end, which is very satisfying.
Lift-Up Conditional
When you inherit difficult code it can take weeks to become productive. Iโd like to show you the difference it can make when you have the right tools for the job and know how to use them.
Once youโve got good tests in place you can refactor much more confidently. In my previous post I showed how to get good tests using Approval Testing. Iโm pretty confident in these tests, so Iโve made a second video showing some initial refactorings Iโd do to get this code cleaned up a little.
One of the techniques Iโm using is called โLift-Up Conditionalโ. Itโs a manipulation of a long complex conditional statement that will let you group together all the statements related to one particular conditional. I havenโt seen this particular refactoring described in the literature before – it was Llewellyn Falco who showed it to me originally. Itโs perfect for the Gilded Rose code which basically comprises one big complex conditional.
The other star of this show is IntelliJ. It has a lot of automated refactorings that come together to make โLift-Up Conditionalโ easy and it makes really short work of cleaning up this code.
This is the second screencast in the series. My aim is to show that with the right tools and refactoring know-how you can quickly become productive with the code, even without fully understanding the byzantine business rules.
Part 2: Refactoring item logic using โlift up conditionalโ
Replace Conditional with Polymorphism
When you inherit difficult code it can take weeks to become productive. Iโd like to show you the difference it can make when you have the right tools for the job and know how to use them.
Once youโve got the code cleaned up to the point where you can see the parts of the logic that belong together, you can start to create a better class structure. A classic refactoring for this is โReplace Conditional with Polymorphismโ which was first described in Martin Fowlerโs book โRefactoringโ.
The basic idea is that you create subclasses to encapsulate the logic concerned with each logical case. Your design becomes much more flexible if you need to add new types that are variations on types that are already there – as in this case.
This is the third screencast in the series. My aim is to show that with the right tools and refactoring know-how you can quickly become productive with this code, even without fully understanding the byzantine business rules.