Thoughts on the legacy code session
For those that know I’ve been running legacy code workshops for the last few months at users groups that have been kind enough to hear me witter on. I’d volunteered to do our session on legacy but in the spirit of collaboration I got two wonderful collaborators (Ian Haworth & Dan Smith) to help. This was fantastic as it wasn’t just my diatribe but was peer reviewed by others. Whereas my solo sessions covered topics such as:
- attitudes to legacy
- characterisation tests
- scratch refactoring
- understanding though story telling
It was agreed by the team that we were putting too much into a session. Ian had been to a session run by the on the Gilded Rose kata. This had a much more focused scope than my session. I’d seen the kata before but never attempted it. During my preparation I had a bash and used the characterisation technique above. When I got back together with the session team it appeared I’d not followed Ian’s guidance properly. He wanted us to use a specific technique, the Golden Master.
Like all good ideas the Golden Master is an obvious one. Probably the one you say in your head before you refactor any legacy code, “I want the outputs to be the same as before the code was changed.”
Here’s how Sandro describes it:
The Golden Master approach
Before making any change to the production code, do the following:
Create X number of random inputs, always using the same random seed, so you can generate always the same set over and over again. You will probably want a few thousand random inputs.
Bombard the class or system under test with these random inputs.
Capture the outputs for each individual random input
When you run it for the first time, record the outputs in a file (or database, etc). From then on, you can start changing your code, run the test and compare the execution output with the original output data you recorded. If they match, keep refactoring, otherwise, revert back your change and you should be back to green.
So with our version we took a run of 30 degradations in quality. Including the effects of the new requirement. (I forgot to mention there’s little value in changing code that doesn’t have to be changed).
The Gilded Rose
The Gilded Rose kata is a shop based around something you may find in World Craft. Classes*(HINT)* of items degrade in different ways. The code is written in such a manner that it is a challenge to make a change safely. Your mission is to make the change and hopefully make the code better.
The groups attempts
The group spent longer than I would have thought on cleaning the code to understand it over refactoring to find a solution that I would have expected. Part of this I put to down to blind pairing (new pairs tend to talk more to try and understand each other better) but perhaps we as facilitators didn’t move the session forward as quickly as we would have wanted. In my mind the solution jumps out as a particular design pattern although in our retro no one volunteered that. Again I think that a short timescale makes developers panic. I think 3 out of the 18 groups got the solution completed. This, for me, illustrates that there is a huge cognitive challenge to doing things the right way where legacy is involved.
The group responded favourably to the golden master. It provided an adequate safety net for the pairs to develop against. In the retrospective we discussed the risk that any randomness in code may render the golden master useless. These factors should be taken in to consideration before using this method. There was much discussion on how far to go and that we as developers refactor beyond what is economically valuable.
For me, the big lights on was appreciating coverage as a valuable metric with legacy. In the way I approach testing I shy away from coverage obsession. I posit that 100% coverage is a waste of resource and that my feelings are that testing every possibility lends its self to brittle code. However with legacy the golden master should be cover all boundaries where simple characterisation tests many not understand the boundaries to cover all eventualities. These outside tests are essential if possible in my opinion.
As a session facilitator this was an excellent evening. It’s great to see devs chatting and enjoying hacking together solutions. It seems that people had a great time too. Thanks everyone and see you at the next one.
Finally if you’ve never read it, buy the book. Working Effectively with Legacy Code is still one of the best books on writing robust code out there.