I’m preparing a coding dojo for my colleges at Iterate where we will try to collectively refactor the “legacy” Hudson/Jenkins, especially Hudson.java, to something more testable, using the Mikado Method. I’ve got the idea after reading Gojko Adzic’s blog on how terrible the code is and after discovering the Mikado Method by a chance. Since a long time I’m interested in code quality and since recently especially in improving the quality of legacy applications, where “legacy” means a terrible code base and likely insufficient tests. As consultants we often have to deal with such application and with improving their state into something easier and cheaper to maintain and evolve. Therefore such a collective practice is a good thing.
The Mikado Method
The Mikado Method, which the authors describe as “a tool for large-scale refactorings”, serves two purposes:
- Exploring an unknown, legacy codebase with the aim of learning enough to be able to perform a particular change
- Performing the change with the minimal risk, that means especially without ever bringing the application into a broken state where it cannot be built or tested
The method itself doesn’t introduce any new refactorings, it is just a “container” for various well-known refactorings and servers as a guide or a map, adding the big picture of where we started, where we want to get, and where we are right now, thus helping us concentrate on that which is important and not loosing sight of our primary goal, which is otherwise rather easy once you enter the swamp of a rotten legacy code base.
The method is surprisingly simple, you need only a whiteboard and a version control system (VCS). The process is as follows:
- Identify the goal you want to achieve – the Mikado Goal – and write it down on a whiteboard
- Implement a naive solution, i.e. try to do a rather simple solution
- If the changes broke your code – so that it doesn’t compile or tests fail – add the things that must be done or satisfied before you can perform the change safely as child nodes to the Mikado Goal and revert your changes to the code base
- Pick one of the new child nodes and go to 2.
- Once you are actually able to do a change without breaking something, you can check the corresponding leaf node of the growing Mikado Graph and continue with another leaf until you eventually get to the original goal and get it implemented
Following these simple steps you go on discovering what needs to be changed without getting broken code base which is impossible to work on or without wandering too far away from the goal that you ultimately want to achieve. It may sound as a waste to undo changes on a regular basis but with modern automated refactorings and eventually backups in a VCS it is a small price to pay for the safety that non-broken code base provides.
The insistence on a naive solution is important because legacy code bases are often so intertangled and complex that whenever you try to outsmart their badness you usually fail, hitting again and again the walls of unforseen problems, dependencies and crazy design decisions. With a simple solution you are more likely to succeed or at least discover the hidden complications before you wasted too much effort and you avoid the trap of “paralysis by analysis”. It doesn’t mean that you should never think and analyse – but do it only when it really pays off, keeping in mind that the code base is usually yet worse than you expect.
To understand the benefits and proper application of the Mikado Method, read the freely available draft of the Mikado Method book and try it on the “code kata” exercises that the authors have prepared for you. Some interesting quotes from the book:
Computer programs has to improve or they are doomed to a slow death. We, the developers, hold the fate of the code in our hands and we are the only ones that have the power to improve it. It is our responsibility to keep the code clean and fit for purpose. This means we have to be able to add code, improve our own code and the code of others.
The Mikado Method helps us visualize, plan and perform business- value-focused improvements over several iterations and increments of work, without ever having a broken code-base during the process. It enhances communication, collaboration and learning in software de- velopment teams. It also helps individuals or programming pairs stay on track while doing their day to day work. It provides us with frame- work to help us morph our system into the desired shape.
We naïvely try to implement a change, without analyzing too much in advance. By doing so, we don’t need to think about how this affect that or the other, something that keeps us from ending up in analysis paralysis.
The key to changing any system is to first change the restrictions enough to make the desired changes possible.
When there are errors we always roll back all our changes! This is extremely important! The reason is that we never want to edit the code when we don’t know what state it is in. Since we have made changes that resulted in errors, we don’t have a stable state to make changes from.
PS: Two of my colleges have mentioned that they used something similar to the Mikado Method without knowing that it existed. That proves that the method is indeed very practical and useful.
The conclusion is yet to be drawn :-). I’ll publish a blog post with our experiences after the coding dojo. Stay tuned.
Update: Outcomes in What I’ve Learned from (Nearly) Failing to Refactor Hudson.