Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Joshua Kerievsky Introduces "Sufficient Design" To The Craftsmanship Discussion

Joshua Kerievsky Introduces "Sufficient Design" To The Craftsmanship Discussion

This item in japanese

Software Craftsmanship has been a hot topic as of late. Joshua Kerievsky posits a possible counter-perspective to the underlying "code must always be clean!" ethos of the craftsmanship movement; something he calls "Sufficient Design". Learn about what Joshua means, and hear thoughts also from Bob Martin and Ron Jeffries on Kerievsky's ideas.

Kerievsky began what appears to be a possible series of posts on his "Sufficient Design" idea with this problem statement:

...some programmers argue that the software design quality of every last piece of code ought to be as high as possible. "Produce clean code or you are not a software craftsman!"

Such advice is well-intentioned. Many of us have seen the near paralysis that comes with high technical debt.

Yet ultimately the craftsmanship advice fails to consider simple economics: If you take the time to craft code of little or moderate value to users, you're wasting time and money.

The fact is, some code simply doesn't need an excellent design, whether that code is a start-up experiment or a corporate application feature.

Joshua goes on to tell a story about his own development team's decision to leave a known design smell in what refers to as the application's "plumbing code", regarding the return value contracted by the inherited "processWith" method of all the application's concrete Action classes. After multiple years of knowing about this smelly code segment, and even a couple failed attempts to refactor it out, he explains it still exists, but that it does not get in his team's way. He asserts that spending time on cleaning up this non-obstructive problem would be unwise as it takes time away from working on more important features. The moral:

We need high design quality for stuff that is critical to our products and less design quality for stuff that isn't critical.
The art of software design is now defined by how well an individual or team can adjust the Design Dial on a feature basis to produce software that people love and which makes money.

There is no one-size-fits-all approach to software quality.

If you're a feature junkie, pushing one feature after another into your product with little thought for software design, your technical debt will paralyze you starting around release 4.0.

If you're a quality junkie, you will over-engineer every last thing you do.

Sufficient Design is where Lean meets Craft.

Uncle Bob Martin, well-known for his leading part in the latest Software Craftsmanship movement, quickly responded with a note that, possibly to some people's surprise, ultimately endorses Joshua's message:

It seems to me that Josh was behaving exactly as a craftsman should. He was worrying about exactly the kinds of things a craftsman ought to worry about. He was making the kinds of pragmatic decisions a craftsman ought to make. He was not leaving a huge mess in the system and rushing on to the next feature to implement. Instead he was taking care of his code.

Martin does also take a moment to clarify his stance that the Craftsmen's message does not ring of "perfection or perish!" as Joshua may have implied:

Craftsmen are first and foremost pragmatists. They seek very high quality code; but they are not so consumed with perfection that they make foolish economic tradeoffs.

Equally expedient was a followup note by Ron Jeffries, another out-spoken proponent of taking time to keep your programming playground clean. His message essentially boils down to a two-fold message, first that design debt is a "pay me now or pay me later" game, and second that we should strive to be able to go fast and go good:

If slacking on quality makes you go faster, it always comes at the cost of longer term quality.

Turning that around, if we were better than we are, we could go faster without cutting quality. We need to improve. Today may not be the day to make that improvement: Today we may really need speed more than we need quality. But the handwriting is on the wall:

If slacking on quality makes us go faster, it is clear evidence that there is room to improve our ability to deliver quality rapidly.

Before long, Kerievsky published "part 2" (of what he implies to be many) of the "Sufficient Design" message, this time stating flat out that sometimes "sufficient" means doing it indeed poorly. He tells another story from Industrial Logic's development vault, this time about a seriously "Large Class" that arose while speedily implementing a "Playlists" feature for a big client release of his eLearning product:

Based on a year of living with the Playlist feature and studying usage data, here's what we know:
  • Our users are definitely using Playlists.
  • No user has ever complained about Playlists.
  • Our users don't rave about Playlists the way they rave about other features in our product.
  • During sales, future clients are happy to hear that our Playlists provide time-efficient learning sequences for specific topics.
So are we paying the price for incurring high design debt on the Playlist feature?


Here's why:
  • No New Behavior — we haven't added or changed any behavior of the original Playlist feature during the last year.
  • Unchanged Code — We've made only trivial changes to UserLibrary (main source of the Playlist design debt) during the last year and those changes had nothing to do with Playlists.
  • An Isolated Problem — The poor design we do have for Playlists is isolated: it hasn't gotten in the way of new feature development in the last year.
Playlists were an "accessory" thrown in to a deal to make our largest client happy.

The feature has been useful but isn't on the critical path of our product development.

The code smells in the Playlist code, such as Large Class and Conditional Complexity, have not slowed us down.

And here's an insight into how we manage quality:

If we decide to give users a more sophisticated Playlist feature, we will happily pay down design debt before making new progress.

Joshua explains that the prospect of dealing with this when a future feature requires it doesn't bother him, in large part because of his team's skill and discipline with TDD, but also simply because he understands and accepts that, just as sometimes low craft is in order, sometimes the dial needs to be turned to high craft too. He summarizes:

So are we happy with the Playlist code from a year ago?

We are happy that we didn't invest more in Playlists than needed at the time.

We'd like to clean up the design but will wait until the time is right.

That is Sufficient Design.

What do you think? Is Joshua's advice applicable generally? Have you succeeded with similar approaches on your own projects? Failed miserably? What else might need to be considered to further the discussion?

Rate this Article