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.
DoSimpleThings in ExtremeProgramming. 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 UnitTests 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.
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.
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
There are second order effects to asking yourself "What is the simplest thing that could possibly work?" -- KentBeck
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."
WhatIsSimplest is a very interesting question to me. -- MichaelFeathers
DoSimpleThings is a simple answer, speaking to one's awesome power to be complex. -- PCP
Isn't this just SmallIsBeautiful applied to programming? -- HelmutLeitner
See DrawingHand for a response to the concerns about simplicity possibly resulting in FlimsyAndBarelyFunctional software.
Suggested as related are SimplestThingReplyFromJamesCollins; SimplestThingReplyFromRonJeffries; XpSimplicityRules; GoldilocksSolution; ManagingEvolutionaryDesign; EvolutionaryArchitecture
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
I DoTheSimplestThingThatCouldPossiblyWork 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
DoTheSimplestThingThatCouldPossiblyWork 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 in 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.
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? -- SteveConover
WhenOneLeafDiesBuyaWholeTree has some interesting and relevant stories.
(quote moved to TimeToMakeItShort)
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 nor 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" nor "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".
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. Mark Twain 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 (see TimeToMakeItShort)
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/ActionForm?/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.
Now, TheSimplestThing 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? - knocte
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 ReFactoring 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.
Its the simplest that will work, but most people find the syntax frustrating or if they aren't programmers, incomprehensible.
Its 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. -- WyattMatthews
This page mirrored in ExtremeProgrammingRoadmap as of April 29, 2006