Joshua Kerievsky Introduces "Sufficient Design" To The Craftsmanship Discussion

| by Mike Bria Follow 0 Followers on May 19, 2010. Estimated reading time: 5 minutes |

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

Adoption Stage

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Sufficient Design = Nonsensical Sophistry by Kent Dorsey

The definition of Sufficient Design presented here reeks of oversimplification of the user stories associated with design "activity" and the criteria used to assess design "quality". If one accepts a definition of design "smell" as misalignment with sustainability, performance, or any other metric designated relevant to the development context at hand, then design smell is simply code waste that could have been avoided.

This is especially true if software development is approached as a lean and agile engineering discipline, instead of a lazily executed black art. The choice of whether to maintain poorly crafted code falls outside of the realm of design activity. Design can only be deemed "insufficient" after the fact, never before. Engineers call such discoveries "defects" and typically assess their impact during operational or release planning. The idea of Sufficient Design is nonsensical sophistry.

The counter argument is simply that the consistent practice of continuous testing, code inspection, and related activities keeps code elegant and lean, which in turn empowers amazingly efficient levels of productivity that are truly sustainable. Do not confuse design skill or thoroughness with management tradeoffs to accept waste and often non-sustainable entropy into a system.

Cleaning up the design when the time is right by Amy Thorne

The trick is in that sentence in bold: "If we decide to give users a more sophisticated Playlist feature, we will happily pay down design debt before making new progress."

In my experience, it's really, really, exceptionally rare for a team to both recognize that they will need to pay down that debt and to actually do so.

As a developer, sometimes I feel like a banker. I need to asses the borrower's likelihood of paying back their loan when it comes due. If I'm pretty sure they won't pay it back, I might not offer it.

But in that case, maybe the "sufficient design" is the one low in technical debt; whereas if the team is more responsible, the "sufficient design" can be the one higher in technical debt?

It may come back to the different kinds of technical debt: "Be Sure You Are Incurring The Right Kind of Technical Debt" and "Ability to Take on Debt Safely Varies."

Low Code and Design Quality == Loss of talent by Slava Imeshev

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.

As a Peopleware covert, I like the idea that lowering quality standards below those that a developer set for himself leads to the loss of interest and to the eventual departure of those who forced to produce low quality products. In other words, there is no justification for low quality in the long run.


Slava Imeshev

Use of the term "Sufficient Design" by Kevlin Henney

It is perhaps worth pointing out that the term "Sufficient Design" is not new. I've used it for a number of years (see, for example,, but with a different emphasis: sufficiency as a counterbalance to speculative generality. What Joshua is actually describing is "Good Enough Design", which is close but is subtly different to Sufficient Design.

Maintenance and Sufficient Design by Suresh S

Cleaning up the design can be due to various reasons. From our experience, one of the major reasons is the poor maintainability of the system or some of the components. Is "Sufficient Design" against this priciple? Is it suggested to clean up design or code only when new features are getting added or customers pay for it? This could lead to increase in the maintenance cost?

Re: Sufficient Design = Nonsensical Sophistry by Joshua Kerievsky

Hi Kent, I think you've misunderstood what Sufficient Design is.

When you run a small business, you have plenty of constraints: income, payroll, customer needs/desires, quality, product improvements/bugs, etc.

My job is to balance those constraints and Sufficient Design helps me do that.

What part of our product's code has made us the most income? I can guarantee you that we spare no expense on that part of the code.

However, when it comes to parts of our code that are less important, we don't go to amazing extremes to produce the best design possible (though we do test-drive the code, so we have good automated test coverage, if and when we decide to mercilessly refactor).

Now, are you saying that all code, no matter how important, should have only a supremely excellent design and anything but that is nonsensical sophistry?

Re: Low Code and Design Quality == Loss of talent by Joshua Kerievsky

Hi Slava,

You're taking an idea and changing it into "Sufficient Design will demoralize you by forcing you to write crappy code." Nope, sorry, that utterly misses the point.

We are ultimately after making Awesome Users (as Kathy Sierra says).

Making every single line of code have a perfect design isn't the best strategy for achieving that goal, as there are *many* competing concerns in product development.

In our shop, we test-drive all code, yet we don't mercilessly refactor all code. Before we work on new features, if we feel the code is messy, we clean it up before adding the new code.

We are constantly making decisions about what a Sufficient Design is, given the needs of the business and the need to maintain high quality.

Sufficient Design can yield excellent, good, ok, poor designs -- all of which depends on constraints and context.

A team of programmers and business folks needs to work together to produce a great result for the users.

Perfect design of every last line of code will get in the way of that most of the time.

A sufficient design for the code that makes you the most revenue and is most important to your users ought to have an excellent design.

OTOH, a sufficient design for code that makes little revenue and isn't important to your customers doesn't need to have an excellent design...until perhaps it becomes super important to your business and users.

That is the kind of thinking we do in Sufficient Design.

Hope that helps.

Re: Use of the term by Joshua Kerievsky

Hi Kevlin,

James Bach's Good Enough Software paper had major influences on how I think about bugs in software and helped me to get over the idea of 100% bug free code. Sufficient Design spans a range from Excellent to Poor design, depending on what is needed, when it is needed, what impact it has on user happiness, sales, marketing, etc. So just to be clear, I don't think of Sufficient Design as always meaning mediocre. It all depends on context, as usual. I read your paper -- thanks for the link and I'll be sure to mention it in future writings about Sufficient Design.

Re: Cleaning up the design when the time is right by Joshua Kerievsky

Yes indeed Amy, it is FAR TOO RARE for teams to recognize and regularly pay down debt.

I'd like to change that.

My hope is that Sufficient Design will help, rather than hurt that cause.

I want to bring more attention to the need to treat super-important code with great care and attention and to roll out mediocre code only to later improve it when it becomes important to the business.

I think the Craftsmanship movement is a bit too far in the programmer's corner and I'd like to strike a balance between those who specify and request features and those writing code.

Re: Maintenance and Sufficient Design by Joshua Kerievsky

Hi Suresh,

Sufficient Design is about adjusting the quality dial based on needs and re-adjusting that dial when needs change. Depending on the context, we find ourselves refactoring before, during and after coding features. We don't refactor code that isn't so important, as we have more pressing items. However, if that code becomes a trouble area for us, then yes, we work hard to improve it.

Does that help?

Re: Sufficient Design = Nonsensical Sophistry by Kent Dorsey

Hi Joshua,

What do I believe? Based upon your extensive descriptions, I simply believe that you have misapplied and misinterpreted the results of agile best practices for management and development during your attempts to balance constraints.

I believe that you are now attempting to rationalize the results. Nothing more and nothing less.

I believe that I perfectly understand both your position and that of your critics.

I believe that Sufficient Design is one possible definition of a set of symptoms for the underlying disease responsible for the destruction of quality throughout the software engineering profession. Thank you for the precise definition.

Like Alzheimer's, this disease is an emergent systemic problem, a result of a human system failing to balance operating constraints.

I believe that you misunderstand the thread running through the arguments of many of your critics, as if they just do not get your point.

The cure for the disease of Sufficient Design is the solid application of software engineering practices. Nothing more and nothing less.

Do the projects in which I am involved always hit the mark or achieve the ideal? Certainly not! We are only human, and we fail.

However, do we choose to defend our failures within the guise of a newfangled method or muddied practice? No. We acknowledge the failure, inspect and adapt, in order to reduce the frail points.

Failure is failure is failure. Sufficient Design is failure. To represent it otherwise is disingenuous at best, cancerous at worst.

I believe we will have to agree to disagree.


Re: Sufficient Design = Nonsensical Sophistry by Joshua Kerievsky

Hi Kent,

Thanks for the reply and I hope you can be patient with me as I try to understand your perspective on the serious mistake you think I'm making.

It will help to get specific.

I wrote about the design flaw in the command pattern implementation we have for handling incoming and outgoing web traffic (

That code works, only I don't like the design. Yet that design isn't inhibiting us, isn't slowing down development, isn't hurting users. It's just an issue of beauty - if I had 54 hours in a day, instead of 24, I'd have already cleaned it up. And as I wrote in the blog, I did try.

Given the many constraints, I'd much rather build an awesome new product (we're working on one) than cleanup the design flaw in the command pattern implementation.

So...are you suggesting that I'm making a huge mistake in that choice, that there is simply no excuse for noticing and not cleaning up a design smell, even if it is quite minor and isn't hampering development or the user experience?

I do sincerely want to understand your perspective.

I've been coding professionally since the late 80s and doing XP/Agile nearly non-stop internally and with clients around the globe since 1999, yet I still have more to learn and hope I can stay humble enough to be open to people/ideas that contradict my own.


Re: Sufficient Design = Nonsensical Sophistry by Philip Schwarz

Hi Kent,

I am interested in your arguments...I want to know more.

You thanked Joushua for his precise definition of Sufficient Design.

You also said: the cure for the disease of Sufficient Design is the solid application of software engineering practices.

What do you mean by solid? Can you give me an example of a solid software engineering practice, and one that is not solid?

As you are no doubt aware of, having concluded that "software engineering is gravely hampered today by immature practices",, has set out to "refound software engineering based on a solid theory, proven principles and best practices". Do you agree with SEMAT that there is currently no rigorous, theoretically sound basis for software engineering practice, and that it needs developing? What definition of software engineering practices do you use? where can I find it?

Philip Schwarz.


Good Economics by Olivier Gourment

I am reading this article and comments again, 4 months after tweeting about it and I still find it one of the most thoughtful propositions I've stumbled upon in months.
This is just Good Economics.
Where I work, we often have to develope features that customers might look, or not... Does it make sense to invest in 2 months of reaching 100% test coverage and 4-5 refactorings if the feature is seldom, if ever, used? Who would pay for this??
Obviously, as Ron Jeffries pointed out, ideally testing and refactoring should not cost more... but it does...

It also reminds me of an article where Kent Beck was critized for admitting that he does do TDD all the time... How shocking!

I'm glad we're finally starting to put things in perspective.

BTW Scrum and other frameworks help with this, by TIME BOXING. Think about it.

Re: Good Economics by Olivier Gourment

My iPhone might have eaten some words... Kent Beck does NOT do TDD all the time..

And my customers might not LIKE/USE the feature (they might also not even LOOK at it, but that was not intended wording)

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

15 Discuss