Start Paying your Technical Debt – The Mikado Method

[at http://mikadomethod.wordpress.com/ we will put more information on the Mikado Method]

A couple of years ago, Ola Ellnestam and I was working on a project where the code was a big ball of mud, or at least well on the way there. Global variables and singletons all across the code base, circular dependencies, deep and fragile inheritance hierarchies etc. The Technical Debt was everywhere.

Copy’n’paste?

All of a sudden we were supposed to deliver to a new client and the interest on our loan went through the roof. The reptile response from several developers on the team was to copy most parts of the code base to a new project and modify the code there. This would double our debt, but decrease the interest temporarily, until the next client would drop in. We fought with all we got to avoid doubling our debt and in the end we had convinced everybody that we could re-factor the code-base, just give us a week or two…

The Hydra

Our approach was that we should do what we needed to do, fix all the compiler errors, run all the tests, check-in, done. Yeah, right…

We did what we wanted to do, got about 20 compiler errors and started fixing them. When we were just about done, the compiler could move a step forward and showed us yet another bunch of errors. When trying to fix them we had to make new re-factorings, that in turn created new errors.  So we went on, and every day on the daily stand-up we said that “We just have a couple more errors to fix, but we will probably be done today or tomorrow”. Yeah, right…

After more than two weeks of working like this, with 1200+ files checked out, 200+ compiler errors we had to face it. We would never make it. We were trying to behead the Software Hydra, but for every head we cut off two more grew out. We had to make the tough decision to revert everything we had done. But, as Tom Poppendieck always say: There is no failure but the failure to learn. And did we ever.

Go with the flow

We had realized that we had been walking with the refactoring dependencies, i.e. we tried to re-factor a part of the code that was depending on that another refactoring already had been done, which it hadn’t. If we could just walk with those dependencies, or prerequisites, until we reached a re-factoring that had no prerequisites, a leaf in the dependency graph, then we could just do that refactoring without any hassle. And by doing that, we would have fulfilled the prerequisites of another re-factoring that now had become a leaf, ready for execution. By doing so with all prerequisites, eventually our goal would be met!

The Mikado Graph and the Mikado Method

The Mikado Graph

The Mikado Graph

When we presented this method at SDC2009, Laurent Bossavit suggested that this dependency graph and dependent refactorings had great similarities with how the Mikado Game is played. In order to get to “The Emperor”, you cannot just pick-up that stick. First you have to pick up all the sticks that in some way is above that stick. We thought it was an excellent observation and we now call it The Mikado Method and the dependency graph is called The Mikado Graph, as suggested by Laurent.

The Naive Approach

In our real-world case, we drew the Mikado Graph on a whiteboard, step by step. To do that, you naively start with the thing you want to achieve and draw that on your Mikado Graph, typically a business goal. Try to implement that change. If that goes all well, you are done. Check-in. Congratulations!

In most cases, however, you end up with compiler errors or tests that don’t run. Examine the errors and failed test and come up with measures that would have prevented those errors or test failures. This is often other refactorings in the application. Those measures become sub-goals to you business goal. Draw them on the graph as well, with arrows pointing from the business goal to the sub-goals. Revert the code to the previous working version.

Now, for each of the sub-goals repeat the process by naively trying to achieve them. Draw the solutions to the new issues as new sub-goals, revert the code, attack new sub-goals and so on. In the end, you can actually implement a leaf sub-goal while the application still works. Great! You just got one step closer to achieve your business goal.

By doing the refactorings from the leaves and in the opposite direction of the dependency arrows, you will eventually achieve your set out business goal.

The Mikado Graph Done

The Mikado Graph Done

Good luck!

About these ads

19 Comments (+add yours?)

  1. eric idebro
    Apr 02, 2009 @ 07:35:04

    Ser ut som en effektkarta.

    Reply

  2. danielbrolund
    Apr 02, 2009 @ 09:16:53

    Eric says: This looks like an effect-map (http://inuse.se, mostly in Swedish)

    As far as I understood it there are great similarities (but I need to buy that book to know for sure). An interesting difference would probably be the naive approach that works well when refactoring code.

    We have only used the method for refactorings, but it is basically how you break down strictly dependent work.

    Reply

  3. Siddharta
    Apr 03, 2009 @ 09:10:21

    Nice article. I like how this method prevents you from going deeper and deeper under water by focusing on small parts of the system at a time.

    Reply

  4. Joakim Karlsson
    Apr 25, 2009 @ 18:05:42

    Great article!

    I love this as a thinking tool to keep runaway refactorings focused on a goal, and as a communication tool to keep the team up to date on the progress.

    I’m stealing this…

    Joakim

    Reply

  5. Rasmus Kaj
    Jun 09, 2009 @ 20:22:01

    Thanks for this article! It certainly sounds like a better approach than what I did a while ago: after giving up on one refactorisation sequence, I just tried again from a slightly different angle, and the third time I tried, it worked … :-) If the graph had been bigger, I would have needed something like this.

    Reply

  6. Sebastian Kübeck
    Jun 24, 2009 @ 14:56:33

    Nice post indeed! The Mikado metaphor really hits the nail on the had!
    One thing I do not understand is how you got so many compiler errors. When I do refactoring or add tests, I don’t change that much at once. Usually not more than I can fix within seconds. I am much too scared that I don’t find my way out of those errors again.
    Furthermore, I check in frequently but only after all tests pass. I usually check in before I finish my work for the day such that I don’t need orgiastic merging the next day.

    Reply

    • danielbrolund
      Jun 24, 2009 @ 15:33:50

      Thank you, Sebastian. I agree that compiler errors are scary. In the hydra-example we underestimated them, to say the least…

      The reason we get the compiler errors (temporarily) is that we use the naive approach.

      A very simple example: Say you get a new client that requires you to move a class into a separate library. With the naive approach, we just move the class, e.g. placing it in a new project. This might reveal several dependency problems in the shape of compiler errors (class missing etc). Note those issues in the Mikado Graph, revert your code and then handle the issues one by one, naively. Eventually, you end up in the situation you describe; where you can do a simple refactoring (naively) that doesn’t break the code. Check-in. Be happy. Go for the next leaf. Eventually, you are in the position where you actually can do the original move of the class without any errors.

      Reply

      • Sebastian Kübeck
        Jun 24, 2009 @ 18:44:32

        Ahhh, I see. You are working in an environment where you do not have a refactoring browser around, so you are using the Mikado approach to resolve dependencies manually.
        Thanks for the clarification!

      • danielbrolund
        Jun 24, 2009 @ 19:59:01

        If you by refactoring browser mean tools like Eclipse or IDEA, then yes, we do have such a tool (it would be a crime not to, imho ;-)). But, those tools can, afaik, only help you do fairly trivial refactorings. When you have an entangled mess, you need to perform a series (or web) of such refactorings to reach the target. The naive approach can partially be performed with such a tool (e.g. move method, move class). When you consume the leaves of the Mikado Graph ‘backwards’, those steps are often such trivial refactorings, and you perform them with your tool.

        If you by refactoring browser mean some other tool that helps you plan and perform series of refactorings, please let me know.

  7. Sebastian Kübeck
    Jun 26, 2009 @ 08:42:00

    Refactoring browsers are indeed a part of the IDEs you mentioned. The name stems from the first refactoring tool (for Smalltalk).
    Unfortunately, I don’t know of a tool that goes beyond that. There are metric tools around (like JDepend) that help with planning. I also found Joshua Kerievsky’s book “Refactoring to Patterns” extremely helpful. However, I am convinced that you know all this already. ;-)

    Reply

  8. Thomas
    Dec 24, 2009 @ 12:32:03

    The important thing I learned is to *revert* the current refactoring before working on the prerequisite goals. This really puts you in the situation that you always only have a single refactoring to overlook. But I also think that the hope of getting to leaf goals that have no further dependencies, ie. that your dependency graph is cycle-free, is, well, optimistic. This might not be true.

    Your example with moving a class to different library might be a good one in this regard. You undo the move, and your code compiles again. Then you work on the subgoals, to accommodate that the initial class could be in the other library. But then the compile breaks again, as you cannot refactor the subgoals with the initial class in its old place. Or move the initial class with the subgoals unrefactored. You have to do both at the same time. You have a dependency cycle. – Does that make sense?!

    I know and love Mikado, but a name like “dependency method” would have been much clearer for me. But maybe that was taken.

    T.

    Reply

    • danielbrolund
      Jan 05, 2010 @ 21:41:50

      Hi Thomas,
      Thank you for your comment! As you say, reverting is *very* important. It can feel like throwing away work, but it really is keeping a clean workspace.

      I think there are several ways around the problem you are posing, but it is hard to say without more detail. Could you give me a more concrete example of where you must do a series of non-compiling re-factorings to reach you goal?

      About the name, you are right in that it is a “dependency method”. We believe that it is good to have a name that relates to something seemingly different, but when you look closer it has the same constraints. This makes a lot of neurons work at the same time, and that is good for memory. :-)

      Thanks,
      Daniel

      Reply

  9. Trackback: Most Tweeted Articles by Agile Development Experts: MrTweet
  10. Trackback: Coding: Effect sketches and the Mikado method at Mark Needham
  11. Trackback: XP2010 « Walk the walk
  12. Trackback: What I’ve Learned from (Nearly) Failing to Refactor Hudson « The Holy Java
  13. Trackback: Dziewiąte spotkanie – Mikado Method | [sckrk] Software Craftsmanship in Kraków
  14. Trackback: Agile India 2013 – I was there! |

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: