If you subscribe to CowboyCoding, without any design, the resulting system is inevitably a big mess.
XP, however, makes the wacko demand that we design all the time, not just before coding.
You have a typo there. You meant to write just not. --PhlIp
We emphatically do not recommend doing no design. We do, however, recommend doing far less paper, UML, whatnot design. We recommend doing a bit of CRC to set your direction, then implementing the objects to ask them how they really want to be designed. We discover good design by implementing the system and by making sure we RefactorMercilessly every time we learn something. This form of combined design/development goes much faster than the longer cycle that is an inevitable part of paper design.
Most of the projects we read about that result in bad software, overruns, and death marches are in fact top heavy with requirements and big design. There is a famous definition of insanity: doing the same thing over and over again and expecting different results.
In part, we can get away with this because we do not allow "crap" code in the system. We don't write it intentionally; we refactor it when it comes out of our fingers anyway; we refactor it when we stumble across it after not doing it perfectly the last time. If you ran across some bad code in something I wrote, you would fix it - probably sitting down with me to do it. If a programmer persists in writing code that doesn't meet our standards, we remove him from the project, probably before he gets back from Israel.
Extreme programmers do understand their problem - and have dedicated customers with them to be sure that they do. Extreme programmers have live, ongoing analysis, not a dry and out of date document.
Extreme programmers do design. We take time up front to choose the SystemMetaphor (architecture). We CRC whenever it isn't clear how to build something; we let the code tell us how the objects really want to interact, and we change them (i.e. change the design) when we learn that. In ExtremeProgramming, TheSourceCodeIsTheDesign.
Again: we do not advocate no design at all. We do advocate jumping quickly into code, because that is where you can really learn the fastest. We jump into code, however, in the context of a very tight discipline of writing quality code, and keeping the code at very high quality. Without that discipline, we could still learn ... but then we'd have to reimplement what you had learned.
XP has been shown to be able to handle very complex problems. C3 has over 2,000 classes and 30,000 methods, and has been evolving while in production for 18 months without bogging down. WyCash went on for years and never buried itself. This ain't no backroom operation. XP is a serious discipline that does in fact challenge some "conventional wisdom". It does so based on past and continuing success of teams that know how to produce quality large-scale software while maintaining the productivity of small entrepreneurial development teams.
Thanks for continuing to challenge these ideas - it helps us express them more and more clearly (I hope), which is key to our ultimately getting them across in book and speech. -- RonJeffries
For the opportunity of enhancing my understanding of XP, I would like to offer another answer to the design question. The issues seems to be related to the DistanceBetweenDesignAndCode?. My understanding is that the XP practice is to test design ideas as soon as possible, and the way to test out a design idea is to write a test, then implement the code. If you can get feedback the same day it is good, but within the same work session is better. So deal out those CRC cards, make it work with the cards and then ProveItInCode?.
The problem with BigDesignUpFront is that it can take ages before the design ideas get tested out in running code. On a project I am aware of that very nearly did a CrashAndBurn?, coding did not start until the 6th month of an 8 month project. Luckily the design was not too far off, but the project missed many essential requirements that only became visible when the customer saw the system in the 9th month. SoftwareEngineering types may say that the project should have done more Requirements work, but 3 months out of 8 should have been enough. With the ExtremeApproach?, end user validation of the system could have started in month 2, not month 7.
For all future projects I intend to minimize the DistanceBetweenDesignAndCode?.
There will always, however, be a larger DistanceBetweenRequirementsAndDesign?, so you need a lightweight mechanism like UserStories to CaptureRequirementsForPrioritization. So when scoping out the project you capture a lot of requirements, you agree to the general development sequence, and then you work down the list. The lower priority ones will take 12 months or more to get to, hence the larger DistanceBetweenRequirementsAndDesign?.
When the requirement gets near to the head of the queue, you need a mechanism to CaptureRequirementsForImplementation, often through the more complete UseCase mechanism. Or you can use the ExtremeApproach? and using the UserStories as a reminder, actually TalkToTheUsers?, find out what they really want now, and then get the Users to write the tests.
Right on, Pete! -- rj
I think JimPerry said "the less you understand about the problem, the more you should design before coding". I believe just the opposite is true. It is when I write the code that I learn. It is not until I learn that I get the design right. Therefore, I should defer as many design decisions as possible (but not more) until after I have coded.
How many guesses do you want in the system (design or implementation) at one time? My answer is "1". I want to put one guess in there. Then I want to test it. If it is wrong, I change it. If it is right, it isn't a guess. Then I can guess again if need be.
The example above of the guy writing what sounds like a horrifically complex piece of software is not extreme in a bunch of ways. Is it possible that a simpler design could have solved today's problem? Were there reasonable functional and unit tests for what was coded so far? Was there any code in the system that had been written but not completed enough for testing?
Once again, XP spends much more time on design than other processes I have used. It just spreads the time out over the whole project, rather than concentrate it in the beginning when you are ignorant. I think the rest of the world is wacko (which is generally not a good sign, mental-health-wise, but there you have it).
And another thing- if you design long before you implement, the chances that you will learn from your inevitable mistakes drops dramatically. Learning research tells us that the time lag from experiment to feedback is critical to the speed of learning. 30 seconds works well for me. 6 months does not. -- kb
I actually said "the investment of time in design should be proportional to the complexity and (un)familiarity of the task at hand", which I consider to be valid and not particularly in conflict with what Kent said above, unless wrenched thoroughly out of context. (I don't say all design should be done before all code, let alone six months before coding, and I have no problem with experimental code for learning; I would categorize a SpikeSolution as design exercise).
Which is not to say that I think all programmers thrive on the same precise model. I do work better when I do design in a different medium than code; sometimes wholly mental, sometimes sketches on paper, sometimes mathematical models, etc. I learn a lot during that phase, but not usually from writing the results down as code. YMMV. -- JimPerry
At a leading consulting company, I experienced several projects with fortune 500 companies in America and Europe. They had a proprietary methodology that followed the WaterFall method of software development. It started with an inception phase, spent two weeks doing a rapid prototyping session, and had design, development, then rollout phases. Many projects suffered from the usual problems. One out of twenty were highly successful. The rest were ugly, nefarious, and driven by business imperative. In other words, their phases each focused on selling the next phase and this usually drove the process.
The prototyping phase was essentially a throw-away, primarily intended to get stakeholders and executives motivated enough to put their checkbooks on the table and sign up for design and development.
In design, you really did an analysis that didn't address important issues, and failed to understand risk. Spin doctors who couldn't do anything, but were like heroin when they talked about it, drove the process. At the end of design, you had disgruntled technical people complaining that it wasn't finished, a hurry at the management level to start development, and a fat 1000-page design document that mostly contained useless specs that were out of date before they were printed.
Development started with people who hadn't been there during design, likely didn't have experience in the technologies used, and project managers tended to be totally non-technical that had a difficult time managing scope (and subsequently risk). During the last half of the original time slated for development, people were expected to work 12-16 hours per day, and eventually every weekend. System test would be around the corner, and you had a huge, bloated system that was untestable, not being tested, and usually lower priority subsystems either hadn't been developed yet or had been neglected in one way or another.
The OhShitAlarm? would go off, meetings would happen, and they would delay the end of development. In addition, they would fly all kinds of senior technical people in who were to help put out fires and regain control of the project. Those technical people would ask for an object model, sequence diagrams, and a data model. They would be given a thousand-page-thick tree-killer, and told here it is, but it's way, way out of date.
I could continue with the story, but I think you all know how it goes. Year delay, divorces, resignations, etc. But the consulting company would still make money and therefore never had a business incentive to improve the methodology. This still happens today.
The best thing about XP is that it's all about the developer from the beginning. Up-front analysis (you mean "design?" WhatIsAnalysis?) through methods like CRC cards, and deriving the SystemMetaphor, are important. I like to catalogue a set of related patterns at this point as well. But then, since developers are the ones who will be driving the process of building the system, it only makes sense to test, code, and refactor in what resembles a system indefinitely undergoing design. During this process, demos are given, users are involved often, alpha, beta, and one or more production versions are released. At some point the project is stopped.
I firmly believe processes like ExtremeProgramming and ScrumProcess are where it's at. I was on a project earlier this year that was a mutt-dog mix of these two methodologies, and it was highly successful. In closing, I look forward to seeing how XP operates in different contexts such as: distributed teams, mission-critical projects, government projects, projects employing SCM, etc.
Good point! Highlight it in your new book, Kent! (-:
OK, something still bugs me about all this. I agree that a paper-light system has its benefits, but the model being proposed seems to require perfect memories of the developers and the customers. In my experience (although of course, it's only AlmostExtremeProgramming) you sit with a customer, have a rambling conversation about a change and then have to carry it all in your head until it's all down in code. If the change impacts several objects or subsystems it might take some time to get it all coded and it's very easy to get interrupted, distracted, or just lose the thread.
I find that holding details in memory is one of the major sources of ProgrammingStress, and I try to minimize it wherever I can. Is there a facet of Xp which solves this problem, or does it really require superhuman memory-monsters or no interruptions?
Address tasks taking about a day's coding. Sit with the customer. Ask questions. Move cards around (with the customer and some developers) until you know the gist of what you intend to implement. Write some notes on a card. Turn immediately to your computer. Write the test for what you are about to implement. Implement just that much, simply. Test it. Make it work. Make it right. Be done same day. Flush memory, throw card away.
The above sounds flip. It isn't. If you only have to hold one thing in your mind, your mind can probably hack it. Give it a shot. -- RonJeffries
In your terms, now that I've viewed the GoldenRules (see StressFreeProgramming): we're working in very small chunks, all the way from user stories down to code; we work together with customers and developers to understand; we test like madmen; we work in small time chunks. Eerily similar ideas, n'est pas? -- rj
Aaah. What I was missing from the rest of the stuff I've seen here about XP is that small mention of "write some notes on a card", and the implicit use of the card in coding. In fact in one of the CRC pages (reference anyone?) a mention is made of sorting out the solution using the cards, throwing the cards away and _then_ starting coding. I can't help thinking that this is the wrong way round, or at least that some notes have to be taken. All it would take is a lengthy support call, fire drill, distracting world event on the web etc. and all that hard work is thrown away. Or have you found out some way of preventing or catering for such interruptions?
We work in pairs, which helps. Lots of people write things down on a card if they think they can't remember between morning and afternoon. The thing we don't do is to write them up as a document, which takes time and generates no real light. Catering to things that rarely happen, like fire drills and world events, is probably not worth an investment. There's nothing really wrong with thinking about things twice once in a while, especially if it saves time overall. -- RonJeffries
A couple of things struck me as I read all this - one is the emphasis in ExtremeProgramming on coding and design being intimate with the coding. I think that is exactly right. One of the big problems is the idea that people who don't even know how to code can somehow generate good designs for programmers to implement. That is largely nonsense.
The early days of HOLs you would find people talking about languages being self-documenting. That goal was largely abandoned, and I think to all our our detriment. We have programmers writing priestly code that is almost unreadable by another programmer. There was a book called the C Puzzle Book which gave a line of code and said "What does this do?" - Phillip Kahn called C a write only language and then gave in and generated Turbo C. Design ought to become an integral part of coding and good language helps that. XP is a step in the right direction I think but it is easy to abuse and I think it is hard to institutionalize. A few examples: 1) PairProgramming will generally be seen by management as having two people do one job (very unpopular idea), 2) Do the Simplest Thing Possible - will be taken as don't really think the problem through just throw code down on paper (oops dating myself there ...) ... there is no doubt that XP is Extreme and will take some selling. Wacko it is not! I think a serious question is whether it scales? -- RaySchneider
Why should it scale? What if it is exactly good at what it claims it is good at? Just leave it at that? -- AlistairCockburn
Beyond "one-liner" APL programs, quite a few C programmers have gone out of their way to demonstrate their ability to write code that "can't be understood." See ObfuscatedCee for more on the "C Puzzle Book" and the "Obfuscated C programming contest"!!!
[RefactorMe: Surely this can get merged into one of the other too-parallel XP pro and cons discussions.]
This page mirrored in ExtremeProgrammingRoadmap as of April 29, 2006