Wednesday, September 19, 2012

Wabi Sabi Design


This month I reached another turning point of my career. After more than 2 years I left the role of technical lead for a big project in a huge enterprise to start a new career in a new nimble and dynamic company.

Looking back at these crazy months I decided to do a kind of public summary of my experience.
In this period I refined my design and refactoring skills while fighting against insane requirements on a very big code base. On top of this we were using a technology (Osgi) which I didn't know at all at the beginning.
In these 2 years, I took many design decisions: some worked well, some worked bad and a few worked much better than I anticipated.

Now for sure it's easy to be wise after the event, but I asked myself if there was some common fact shared among all my bad decisions (or good decisions for what it matters)...
Well, after the analysis my answer is no. At least I'm not able to discern anything like that.

But the real big lesson has been that I don't believe anymore in such a thing like the final ultimate super-duper design. Sprint after sprint, I saw things that seemed very good solutions at the beginning became a nightmare to change and maintain. Instead many half-baked designs I was a bit ashamed of, with time proved to be rough gems, very easy to change and adapt for new requirements.

As time and sprints passed, I found this fact affected the way I write my code. I didn't aim anymore for a finished, polished design, instead I go for something that I call "wabi-sabi design".

---

In Japanese culture wabi-sabi is a concept derived by Buddhism. Literally it means something like "sober and patinated", but we can translate as "The beauty of things imperfect" or "refined elegance".

A picture is worth more a thousand words so here we have 3 top examples of wabi-sabi.
The imperial villa of Katsura (compare it to the contemporary Hampton Court Palace)

A Raku-style tea bowl (compare it with a Meissen tea cup)


A tea-house (no comparison here)


Incidentally note that although it seems very similar to modern design, wabi-sabi is very different from Minimalist ideals for example. The goal here is not to eliminate decoration but to embrace the impermanence of all things.

---

Now the if there is something that reminds me of impermanence, that's our requirements!
So what does this means in practice? well it's hard to explain but the idea is to let you design to be solid on the fundamentals but unfinished on the details.
A quick check list could be:
  • Don't over-refactor it.
  • Don't impose wide-scope design constrains.
  • Don't lose flexibility pursuing perfection!

I think there are at least three best-practices in the agile zoo which have a strong relation with wabi-sabi design.

One of the best advice I ever received about software architecture came from Mary Poppendieck at the XP conference in 2005. She explained how the best moment to take a decision is always the Last Responsible Moment. Practicing LRM taught me the virtue of patience and the art to design open solutions. In this way you can defer to take a decision about facts which are still unclear.
But stil, until recently, I considered LRM as a temporary thing. Surely there will be a moment in which everything is clear and defined and we can took all the decisions once for all!
Well, I realised that in all mine 18 years of experience I never met such moment. Unless when a project is cancelled, that is.
So are we designing for the moment of the project cancellation?
I think what LRM is really telling us, is to start to appreciate the unfinished design now, because there will never be a finished design in an lively project.

Wabi-Sabi design works very well also with YAGNI, as you can imagine. The easiest way to keep things simple is not to start at all things that you don't really need. How many times do developers write lots of complex code to solve complex problems which don't exist outside their (brilliant) minds?
Or on the other side how many times I heard programmers say that it's not possible to implement a new feature because "the architecture doesn't allow it". More often than not, this means only that someone imagined in the past how the new feature would be, but the reality had different ideas.

Finally another interesting affinity is with the Open Closed Principle (the O in SOLID). The tricky part of OCP is always what to close and what to keep open, but there is no doubt that the more a design is "polished" the more is closed. Keeping classes small, simple and unfinished make them also very open to new extensions.
Usually the is the very last refactoring, the one about "I need to remove that little imperfection" which creates big headaches and makes our software brittle.

---

There are two possible critiques regarding wabi-sabi design:

  • Isn't this wabi-thingy just a way to justify the fact that you are unable to write clean code?
  • If everything change, why bother to design at all? Let's write and rewrite spaghetti code every time they change idea.

I think the first is a potential risk, while the second is a viable option for some kind of projects but it doesn't scale at all for big projects.

But rather than reply directly I'll try to explain what I mean in the next post with a couple of the real code examples.


Stay tuned!



No comments:

Post a Comment