- (if you're not sure what to do yet)
"All that is complex is not useful. All that is useful is simple." -- MikhailKalashnikov
Resist being so greedy when seeking the 'simplest' thing today that the 'simplest thing' tomorrow becomes AddingEpicycles.
. This enables design via two rules:
First, implement a new capability in the simplest [SimplestOrEasiest
?] way you can think of that "could possibly work". Don't build a lot of amazing superstructure, don't do anything fancy, just put it in. Use an if statement, even. Make the code pass the UnitTest
s for the new feature (and all features, as always).
Second, and this is critical to the rule, refactor
the system to be the simplest possible code including all the features it now has. Follow the rule of OnceAndOnlyOnce
and the other code quality rules to make the system as clean as it can possibly be.
With each increment of an IterativeDevelopment
, one should do the simplest thing that could possibly work. To do this, you have to know at least two ways to do the thing. That way, you can at least pick the simpler, if not the simplest.
Know that the ways could possibly work. We do not mean will
work, we mean could possibly
work. You need to be pretty sure it will work, but you don't have to prove it. Why? Because when you try to implement it, your implementation will tell you whether it does
work. Your tests will run, or they won't. It will feel good, or it won't. (Contrast this with the EinsteinPrinciple
We're not looking for the quickest way; we're looking for the simplest result. So, we first break the existing method into pieces. That leaves the existing test cases running. Then we modify (simply, now) one of the little methods to handle the next test case. (KB)
Occam's razor. (JWRC)
Simplest does, however, mean a minimal solution. Don't build a giant super-efficient object, sorted and hashed and linked together, if an Array will do the job.
Simplest might mean "just use a Dictionary". It might mean "create a little object". It might mean "refactor the part hierarchy so that entitlements and deductions both have positive balance when they are normal".
What it does mean, however, is to pick something you can do and do quickly, so that you can get on with the other things you really need to do. Then do that thing professionally and well, complete with all appropriate refactoring.
As for the things you're gonna need: YouArentGonnaNeedIt
. [But don't forget when YouAreGonnaNeedIt.]
One final note: ExtremeProgramming
rests, I believe, on the assumption that developers want to do well, and that when they know what is expected, they will do well. We do, as a team, require that our rules about testing and other key processes be followed. In almost every case, that works just fine. If a developer doesn't follow the rules, we correct or remove them.
- <humour>The developer? Or the rules?</humour>
Combine the S
implestThingThatCouldPossiblyWork with extremely broad-spectrum goals and you get a U
nifiedModelOfEverything. Remember that you can't make anything simple (or, more accurately, simplest
) until you fully understand it; therefore, to truly DoTheSimplestThingThatCouldPossiblyWork
, you need to know everything there is to know about the problem, which means B
igResearchUpFront. However, what most people think or intend when they hear or say "DoTheSimplestThingThatCouldPossiblyWork
" is: take the simplest approach you can think (right now!) for solving the immediate problem
, paying no attention to how a simple solution to the immediate problem might affect the overall complexity of the surrounding context. I.e. it references a greedy heuristic for creating a plan by taking a bunch of 'simple steps', despite the fact that all those simple steps might ultimately form a path that is considerably more complex and potentially far less efficient than doing a bit of BigDesignUpFront
and either scaling the daunting walls or blasting straight through the mountain. This is often combined with refactoring to some good effect, as abstractions and simplifications arise from the morass of greedily written code. However, the 'S
implestThingThatCouldPossiblyWork' almost never involves writing a B
oostLibrary or inventing and implementing a DataModel
or creating an entirely new programming language before you start on the core of your project, no matter how much simpler your overall project (including the associated complexities of the pre-implementation labor) becomes after having implemented it.
There is great beauty and elegance in SimpleThings
, but those who scoff at BigDesignUpFront
, arguing YouArentGonnaNeedIt
, would never
see it - at least not without the aide of giants with big thoughts and bigger designs. YouArentGonnaNeedIt
won't ever get a compiler built. That said, once the big design is running and simplifies everything else, the YouArentGonnaNeedIt
guys will grab it and run because that becomes the S
Of course, there are other reasons for D
oTheSimplestThingThatCouldPossiblyWork in the greedy fashion typically intended by use of the phrase. From a management perspective, it is far easier to parallelize than is BigDesignUpFront
. Giants with big thoughts and bigger designs tend to be singular, slow entities that often can and are willing to take years to get everything right. One cannot
allow programmers to wait on these behemoths, no matter how world-shaking their creations may become. And management should be doubly wary of supposed 'great designs' after considering the false positives - the consultants and the charlatans, the people who believe they are movers and shakers (possessing an ego that could battle any giant bloody) and those who just want you to believe that they are. Either of them will sell you snake-oil in a cellophane package (though only the charlatans will actually know they're doing so).
There are second order effects to asking yourself "What is the simplest thing that could possibly work?" -- KentBeck
- You get done sooner
- Your work is easier to communicate
- Duplication is obvious, so the needs and means for refactoring are clearer
- Tests are easier to write
- The code is easier to performance tune Or, at least, there will be more scope for tuning performance
- You feel less stress, which enhances all of the above
This began as a question, maybe too long for WikiCase
So when I asked [KentBeck], "What's the simplest thing that could possibly work?" I wasn't even sure. I wasn't asking, "What do you know would work?" I was asking, "What's possible? What is the simplest thing we could say in code, so that we'll be talking about something that's on the screen, instead of something that's ill-formed in our mind?" I was saying, "Once we get something on the screen, we can look at it. If it needs to be more, we can make it more.
From the third page of this interview bit: http://www.artima.com/intv/simplest.html
Also see SomethingOnTheScreen
Maybe more exact title would be MakeTheSimplestThingThatCouldPossiblyWork
I'm happy to see that for more and more architects, DTSTTCPW leaves out object orientation.
Recently, I rewrote some C++ code that was part of a controller. It consisted of two inherited classes, 40 functions, and 1,500 lines of code. The result is written in C and has no classes, six functions, and 300 lines of code. I find it remarkable that, when confronted with evidence to the contrary, progress in OO continues. -- ThomasNiemann?
Any evidence that actually supports the benefit of procedural code vs OO, as opposed to the original code being written by an idiot and your code not?
Quality is terribly important in payroll. Airplanes won't fall out of the sky, but the factory could go on strike, and you could make tens of thousands of people very angry. There is no reason why simplicity and quality are in conflict: in my experience, they go hand in hand.
Remember, however, that "quality" is probably impossible to fully define. Accuracy in a payroll system is only valuable up to a point. No one expects a US payroll system to accurately deduct income taxes; it is expected that each employee will have to make a manual adjustment with his yearly income tax filing. Variation, however, is usually not accepted. Depending upon the system, one usually expects a consistent total amount from period to period or expects a consistent pay rate from period to period. Increased accuracy in withheld taxes would probably be judged as lower quality if it lead to wider variation in the amounts on pay checks. In the end, the "quality" of a software based system must be sufficient to meet the expectations of the users; the purpose of the system is really immaterial to the argument. [Please note, the intent of this is not to denigrate accounting systems, but rather to highlight the subjective nature of "quality".] -- WayneMack
Not so. Phil Crosby developed an entire school of thought on defining quality in non-fuzzy terms. Quality, very simply, is conformance to requirements. You can measure how far out of conformance your system is, so you know if it is a "good" system or not. The hard part is establishing the measurements, but domain-knowledgeable people can always find a way to do that.
Crosby measured this stuff in terms of cost: the price of conformance (what it takes to make sure your system is conforming), the price of non-conformance (what it costs your business to have a crappy product), and the overall cost of quality. Crosby showed that QualityIsFree
for every product and system that Phil Crosby Associates ever analyzed. Legions of acolytes have done the same in proceeding decades.
Be sure to see the ShakerQuote
that starts, "If it is not useful or necessary, free yourself from imagining that you need to make it."
is a very interesting question to me. -- MichaelFeathers
is a simple answer, speaking to one's awesome power to be complex. -- PCP
Isn't this just SmallIsBeautiful
applied to programming? -- HelmutLeitner
for a response to the concerns about simplicity possibly resulting in FlimsyAndBarelyFunctional
Suggested as related are SimplestThingReplyFromJamesCollins
I think DTSTTCPW and XP look like a TetrisAnalogy
. -- FrancisTownsend
One little step at a time, lest I be presumptuous, lest I hurt myself, lest I hurt others. -- JoanHalifax
It means one knows everything about programming there is to, but only applies one technique at a time.
I tell a story about discovering the extremeness of DTSTTCPW at SimplestVersusRight
. -- MitchellModel
Where I am having difficulty here is that 'simplest' has no metric. So "the fewest programming environment operations to get the next test case running" could actually be what is meant. Or, "fewest lines of source code". Or, "source code using the what-I-consider simplest types of operations". -- AlistairCockburn
The 'do' in DoTheSimplestThingThatCouldPossiblyWork
isn't how you get to the design; it's what is done in the design
. "The fewest programming environment operations to get the next test case running" is a possible way to get to a design. It's almost
irrelevant in discussion of the simplicity of a design itself. -- rj
when I adhere to ComputerLinguisticMonism
when designing an ArtificialIntelligence
. -- RobertGoodwin
At each iteration in the evolution of the design, Fewest may well be Simplest. But CruftMultiplies
and that simplest way to get from Design N to Design N + 1 is not as simple. -- KielHodges
entails two (2) steps: first, implement the thing in a simple straightforward way; second, refactor the code to produce the simplest system including the new thing. In XP, we have an explicit rule and practice to keep cruft from multiplying. When we do this (and of course we can screw up), it seems to me that fewest is simplest. I was asking you to support FewestIsntSimplest?
in the XP context. -- rj
Refactoring lets one go faster; I've long been convinced of that. But one also goes faster by initially implementing the thing in a simple straightforward way. I - and probably others - need to let go and allow myself to do that. -- KielHodges
It occurred to me that DTSTTCPW has a near relative, SimplifyTheRequirements
. Of course, once you have simplified the requirements, you can still DTSTTCPW. However, you might not think to simplify the requirements - most people don't explore the dimensions of negotiation in them. -- AlistairCockburn
This concept has been churning in my mind for a number of days. I can definitely see advantages with minimizing the risk of over-engineering the code. The subsystem builder in me is a little bothered however. What I'd be concerned about is that by concentrating on the simplest thing possible you might be painting yourself into a corner. I am having trouble coming up with a good example however. I think the word simplest is bringing up the wrong connotations in my mind. I'm equating simplest with quickest, which I don't think is what this is about. Perhaps a better way of saying this is "implement the simplest architecture that could possibly work". -- GlenStampoultzis
We're saying more than that, or less. We're saying consider all solutions to your task that could possibly work. Implement the simplest solution. Refactor from there if and when needed. We're saying that if you build your objects properly you won't ever paint yourself into a corner. And we're saying that when you do enhance the simple solution (and you generally will), you will always wind up with a system that is just right for what it does so far. And we're saying that that is just where you want to be. Everything just right, nothing added that isn't needed. -- RonJeffries
Moreover, the cost of recovery from painting yourself into a corner is arguably (much!) less than the cost of big up-front design which tries to cover lots of contingencies. It depends on the corner, but I bet it'll take less time to recover from an average
corner than it'll take to complete an average
big up-front design. Obviously, average
is a very loaded word in this context. -- BrentNewhall
I have found the opposite to be the case. I have found that I am much more likely to paint myself into a corner when I try to do an expansive design. It is far easier to add something to a simple design, when needed, than having to tear apart an extensive design that is not quite right. Too many times, what looks right on paper now has obvious problems when someone tries to use it a year later.
Here's a way to really ground the DTSTTCPW concept:
Customer: We Want It We Don't Want It
Departing Programmer: I did it my way
Customer: We Want It We Don't Want It We Want It
Departing Programmer: I did it my way
Customer: We Don't Want It We Want It We Don't Want It
Departing Programmer: I did it my way
Customer: We Want It We Don't Want It
Departing Programmer: I did it my way
Customer: We Want It We Don't Want It
Repeat, ad infinitum.
The worst case is that each of these programmers implements half of their giant superstructure according to their tastes during their time on the project. The 3rd programmer sees a confused muddle.
Best case is they each DTSTTCPW.
Is DTSTTCPW another way to say "elegance"? I have to admit that good code gets cleaner and simpler as it evolves, but evolution takes effort. I'm afraid that "extreme programming" will be just a synonym for the usual boneheaded 24/7 DeathMarch
, in the wrong hands. -- DaveOshel?
No, it's saying if you're not sure what to do yet, do the simplest thing you can think of.
Is there a methodology that would prevent a project from becoming a DeathMarch in the wrong hands?
'Yes: Keep it out of the wrong hands. How ? Buy asserting the truism that simple results do not result from simple minds, and that simple does not mean easy
has some interesting and relevant stories.
(quote moved to TimeToMakeItShort
Argument against DoTheSimplestThingThatCouldPossiblyWork
: A technician came to install a water purifier system under our sink. In the process of bolting it in, he/she blocked access to the garbage-disposal power access plug. Later, our garbage-disposal stopped working, but we cannot replace it without unbolting the water purifier first to unplug the disposal, which is not a simple task due to the odd angle. Common sense would dictate at least putting in an extension cord for the disposal plug.
How many people looked at the original installation and did not see a problem? Yes, it is easy to see in hindsight what might have been a better way, but that does not mean it would have been obvious at the time. At the time of installation, it appears no-one considered access to either the garbage disposal or the water purifier system mounting bolts. The problem is not the definition of "the simplest thing" but rather "could possibly work". The definition of "could possibly work" has changed since the installation. For a mechanical change like this, it might have been cost-effective to plan for more eventualities; however, for software systems, there are really no analogies to "blocked access" or "odd angles". The cost and effort to change things in software is very low and (arguably) it is lower than the cost of planning, and the changes rarely lead to scraped knuckles.
An extreme example is to not put safe-guards for nuclear missile launch panels UNTIL the world has been charred. I believe it is reasonable to have a rule, "don't block plugs (outlets)" even if a specific problem with it has not been identified. It is similar to "don't hardwire the same constant in multiple spots in a program".
I disagree with DTST. SoftwareDevelopmentIsGambling
, or perhaps better stated as "investing". Some future-proofing can pay off if you know how to manage it right. It is a matter of understanding the trade-offs and risks. Investors take risks knowing, or hoping, that in the end the total benefits exceed the problems. Perhaps when you are green, DTST is a safer mode, but if you have experience, dammit, use it! -- top
There are reasons for the experienced to hold back. DTST is also a good way to get very experienced people to work together without spending endless hours explaining their great ideas to each other at the whiteboard. Real systems get complex enough just solving real problems without revisiting every greybeard's ancient history. -- WardCunningham
I find it sometimes helpful to distinguish between "the first", "the easiest", and "the simplest" thing that could possibly work. It often takes years of evolution for a design to finally acquire "the simplest" form - I think this is why we have refactoring browsers and unit tests. Similarly, one difference between a "greybeard" and a "rookie" is the former's intuitive insight into "simple" solutions that work. MarkTwain is alleged to have written to a friend "I didn't have time to write the short letter I promised, and so I've written a long one instead." -- TomStambaugh
may have said something to the effect as well, but I believe BlaisePascal
is the original author of that statement (see http://palimpsest.stanford.edu/byform/mailing-lists/exlibris/2003/07/msg00105.html
It seems to me that this will cause software development to become very boring. I can't speak for anyone else, but I find repeatedly blasting database values onto the screen in the simplest way possible to be MindNumbinglyRepetitiveWork
. Saying to DoTheSimplestThingThatCouldPossiblyWork
sounds to me like saying you should put on blinders, turn your brain off and become a CodeMonkey
. It seems to take away the excitement of playing around with ideas that are bigger than 'create another boring e-commerce site'... While I recognize that ComplexityForTheSakeOfComplexity
has no business value, there has to be some point at which code that doesn't directly accomplish the task at hand is justified... Doesn't there?
As an example, I am working on a web application to help judge the success of marketing through different channels. The project uses JakartaStruts
, and there are a lot of standard CrudScreen JavaServerPages
/Action sets for populating and reporting on the system's various business objects. It's the same kind of stuff that I've done on countless other projects... The code to validate a bunch of user input and throw it into the database, or take it out of the database and throw it to the client follows the same patterns I've done a hundred times.
would just be to implement these actions according to spec and get it done with. But that doesn't help when in a month I get another project that does similar things. Now, I've spent X times 2 units of time writing this CRUD code. Realizing this, I abstracted a lot of the code into a CRUD framework that greatly reduces the amount of code in the Struts actions. This is now part of my company's IP, and can be used to shorten development time on future projects.
Obviously, this was not the 'simplest' thing that I could have done, nor was it mandated by the requirements for this project. But it has value, and made the project more interesting for myself. It would never have happened if I only did the simplest thing that could work. Am I an EvilProgrammer?
for wasting the customer's money like this, or am I just not understanding this principle very well?
You probably had used DoTheSimplestThingThatCouldPossiblyWorkFirst?.
You can only reuse what you can use. Get to 'use' with DoTheSimplestThingThatCouldPossiblyWork
. Refactor if you have the same problem again, as reuse would be the simplest thing. D.
I agree: Refactoring does not have to be only on a per-project basis. If your group is working on multiple projects that are unrelated, but you find that you are violating DontRepeatYourself
, then I see ReFactor
ing into a shared library the answer to DTSTTCPW. There are limits though to inter-project refactoring, I suspect, due to library size or number of libraries required. The point is, the shared library is a simpler solution
than duplicate code (fulfilling the same purpose in multiple projects) and the complexity is hidden
behind a common interface that is now group, department, company, or industry wide. Hence standard libraries will, and should evolve, but remember the old adage "KISS" - Keep it simple [insert favorite ending here].
A counter example is wiki.
It's the simplest that will work, but most people find the syntax frustrating or if they aren't programmers, incomprehensible.
It's the simplest thing to a programmer.
Simple may be relative to the usage. People may prefer bbCode, HTML, or other emphasis techniques instead of WikiML, because they are familiar with it. Assuming DTSTTCPW was followed, would it be easier to replace the edit engine or would it be more complicated to support both? I am assuming that DTSTTCPW and OAOO would require that there is a single entry point for rendering a page written in WikiML, a simple addition or change to the function calls made in that module may be all that's needed to support N editing styles or completely replace the one we currently use.
, then Refactor implies a rewrite; I think it has connections with PlanToThrowOneAway
and to some extend, WorseIsBetter
. -- Astrobe
Sorry, but DoTheSimplestThingThatCouldPossiblyWork
is too long of a page name. It could be simpler. This page disobeys the law. See AhSimple
. Another possible name for this could be BetterSorryThanSafe
I like this page a lot. -- EricMangham?
Different people find different things simple vs. complex. A program built to be simple for someone who thinks logically but not inductively will be very different from a program built to be simple for someone who is the reverse. -- JonGrover
I live by two rules summed up by the two following quotes. -- JonathanCrossland
"Simplicity is the ultimate sophistication" - Leonardo DaVinci?
"Everything should be made as simple as possible, but not simpler" - Albert Einstein
I take exception to this rule when past experience has extra weight - DoTheSimplestThingThatWillProbablyWork
and if all else fails DoTheEasiestThingThatCouldPossiblyFail
and then rely the ITMB excuse if your pressed for EpicFailureSyndrome?
. (I Tried My Best)