Deconstructing XP
By Jack Ganssle
Scrum, XP, TDD, FDD, DSDM, PSP, RUP and so many other acronyms that describe various development processes pepper the literature of software engineering. Sometimes it feels like we're as subject to fads as the fashion industry. Most fall under the general moniker of "agile development", a decade-old movement that's pushing against traditional big up front design (BUFD).
The embedded world's denizens are engineers; we're a mostly conservative lot, not prone to radical restructuring of political institutions, our personal lives, and most of all our development processes. BUFD is still an accepted practice in firmware development. At the start of a project we whip out Microsoft Project and start diddling triangles against dates, struggling to develop The Schedule, the map which supposedly guides the entire project. The result is a waterfall model, a sequence of activities beginning with finding requirements that progresses through specification, design, coding, test, and shipping.
The boss then recoils in horror at the 8 month lead-time we anticipate. "The show is in two months - it's gotta be done by then. Or you're all history."
We fire up Project again, and slide the bottom triangle waaay to the left. Errors pour off the page as the tool warns of conflicts. We juggle subtask triangles, taming the tool, creating what we hope is a believable schedule. Not that anyone does (except the boss - "you promised me!."), but if we can stave off the inevitable failure for even a few months then just maybe a miracle will save us.
Oddly, current thinking is that this is dysfunctional and never leads to success.
Various luminaries created The Agile Manifesto (http://agilemanifesto.org) as a response to the BUFD's flaws. Their seductive arguments contain much wisdom, gleaned from too many failed projects. Observing that requirements change throughout the project, Agilers embrace change -they welcome modifications at every phase of the project.
They believe great programmers make the best team members. Well, d'oh. But I wonder what happens to the less than great developers. It's statistically impossible for everyone to be above average. Managers cannot ignore the fact that some team members just won't be as awesome as the agile crowd demands.
The agile crowd disses the schedule. Great software takes time; it'll be done when it's done. Though there's much truth there, very real business pressures demand schedules that we adhere to. Sometimes it's geometry that governs deliveries - there's only a very narrow window that happens every couple of years to launch a spacecraft to Mars. Miss it, and you physically cannot deliver the mission for years to come. Less dramatically but just as important is insuring adequate cash flow: get the product out so the company can pay its bills.
The most visible agile method today is eXtreme Programming (XP). Software literature abounds with stories of XP; some 20 books promote the idea. Originated by Kent Beck, enhanced by dozens of others, XP sometimes seems to be taking the software world by storm.
XP's philosophy is that everything changes all of the time. People, tools, requirements, features and the code are all in a constant state of flux. Instead of trying to immobilize the world, to institute a halt while we generate a project that meet's today's specs, XPers embrace and even try to provoke change. Beck believes that software projects work best when guided by many, many small course corrections rather than just a few big ones. As he puts it "The problem isn't change, per se, because change is going to happen; the problem, rather, is the inability to cope with change when it comes."
That's a laudable concept. However, the implementation leaves, in my opinion, much to be desired.
Traditional software engineering attempts to delay coding till the requirements are nailed down. In XP the code is everything. Jump in and start coding today. To quote advocate Ron Jeffries "Get a few people together and spend a few minutes sketching out the design. Ten minutes is ideal - half an hour should be the most time you spend to do this." Then start coding.
Needless to say that's a radical notion, one that frankly terrifies me. Embedded systems usually don't have a Windows Update feature. They've got to be right; in some cases errors can lead to death. 10 minutes of design is not the path to carefully-analyzed software.
XP takes a few software engineering ideas which work, and, as they say, turns the dial up to 10. If code inspections are good (and they are), in XP all code is inspected all of the time. In fact, programmers work in pairs, each pair sharing a single machine. They take turns typing while the other audits.
If tests are good (and they are), then tests define functionality. Developers create tests in parallel with the code; no function is done till it passes all of the tests.
If customer interaction is good (and it is), then in XP you may not develop any code unless a customer lives with you, spending 40 hours a week with the team. The on-site customer compensates for no spec; developers constantly lob questions at this (presumably savant-like) team member.
If bad code should be trashed (and it should), then all code is "refactored" (rewritten) whenever it can be improved. By any team member, since everyone is responsible for all of the code.
There's a lot to like about XP. It's a fascinating and very different approach to the problem of developing software. I'm entranced with their test-first, test constantly, and don't move on till the tests pass philosophy. If only most of us practiced such aggressive checking! Refactoring is also a great idea, though I'd argue that we should attempt to write great code from the outset, which minimizes the number of refactorings needed.
Unfortunately XP has grown into a bible-thumping religion (the bible, though, is in this case eXtreme Programming Explained, Kent Beck, "refactoring and pair programming". There's been a paucity of counter-reformation ideas. Till now.
Like Martin Luther's 95 thesis, Matt Stephens and Doug Rosenberg's new book "Extreme Programming Refactored", Springer-Verlag, NY NY 2003, ISBN 1-59059-096-1) lifts the hood on the hype and exposes the problems that come with XP.
Just as educated Christians should read what's available of the Talmud (at least, the little that's been translated into English) to understand better an important and interesting part of our world, all educated developers should go dig through a couple of XP tomes. And then read this book, which in the Agile spirit I'll acronym to XPR.
It's the most infuriating programming book I've read. The message is spot-on, but is told in such an awful manner that it's sometimes hard to hear the reasonable thoughts for the noise. Like the lyrics to 40 (I counted) annoying XP-bashing songs littered randomly in every chapter.
Sometimes witty, it's often entertaining in the manner of the National Inquirer or a car wreck. Though the authors repeatedly express dismay at how XP zealots attack their doubting Thomases, XPR wages near-war against the XP personalities. An entire chapter belittles the opposition's personas. A special overused icon warns the reader of yet another tiresome bout of sarcasm.
XPR carefully and correctly demonstrates how all 12 of XP's practices are interrelated. Drop one and the entire game falls apart like a house of cards. Testing is the only defense against poor specs; pair programming an effort to save the code base from a poorly thought-out, frantically hacked-together creation. The book is worthwhile for this analysis alone. The XPers don't stress how vital all 12 steps are to success on a project.
Yet the authors, in the few demonstrations of failed XP projects they present (no successes are noted), sheepishly admit that none of these programs were built using an unmodified form of XP. All used subsets! the very approach XPR demonstrates cannot succeed. So the credibility of these examples suffers.
A sidebar cleverly titled "The Voice of eXPerience" quotes disgruntled programmers who used (subsetted) XP. Actually, I think there are two programmers quoted, the same ones over and over. One pontificates: "My feeling is that XP wouldn't score highly at all when compared to other available principles". That may be true, but isn't a very convincing demonstration of proof.
The authors do miss a couple of other arguments that indict XP-like development processes. The Agile community calls the test strategy XP's "safety net"; they say it insures bad code never makes it to the field. Yet study after study shows tests don't exercise all of the software - in some cases less than half. I'd argue that tests are the safety net that catch problems that leak through the code inspections, design checks, and careful design. In the embedded world, the automated tests required by XP are devilishly hard to implement, since our programs interact with users and the real world.
XPR completely ignores embedded systems, rather like, well, rather like every other software book. One anti-XP argument for an embedded project is that without some level of up front design you can't even select the hardware. Do we need an 8051 or a Power PC? Is data trickling in or gushing at 1M samples per second?
XPR concludes with a modified version of XP that's less eXtreme, more logical, and better suited to firmware development. That chapter is the best part of the book.
Now don't get me wrong- I do believe there are some programs that can do well with XP. Examples include non-safety critical apps with rapidly changing requirements that simply can't be nailed down. Web services come to mind. I know of one group that has been quite successful with XP in the embedded space, and numerous others who have failed.
Should you read the book? If the siren song of XP is ringing in your ears, if pair programming sounds like the environment you're dying to work in, read XPR today. Others wishing for a balance to the torrent of pro-XP words flooding most software magazines will find this book interesting as well. If it had been a third as long, without the revisionist Beatles lyrics, and, well, more polite, it would deserve 5 stars.
XP's motivating guru, Kent Beck, also has a new book out. Test Driven Development (Addison Wesley, 2003, ISBN 0-321-14653-0) focuses on XP's testing practice.
I bought the book because I'm fascinated with testing. It's usually done as an afterthought, and rarely hits the hard conditions. Unit tests are notoriously poor. The programmer runs his new function through the simplest of situations, totally ignoring timing issues or boundary conditions. So of course the function passes, only to inflict the team with agony when integrated into the entire system. XP's idea of writing the tests in parallel with the code is quite brilliant; only then do we see all possible conditions that can occur.
Beck argues for building tests first and deriving the code from these tests. It's sort of like building a comprehensive final exam and then designing a class from that. An intriguing idea.
But - what if the test is wrong? Test driven development (TDD) then guarantees the code will be wrong as well.
Worse, TDD calls for building even the smallest project by implementing the minimal functionality needed to do anything. Need a function to compute the Fibonacci series? Create the simplest possible test first - in this case, check to see that fibonnaci(0) is 0. Then write a function that passes that test. Try fibonnaci(1); that breaks the test, so recode both the test and the function. Iterate till correct.
The book shows how to build a factorial program, which results in 91 lines of code and 89 of test, after (gasp) 125 compilations. Klaxons sound, common sense alarms trip.
Agile proponents love the interactive and fast action of this sort of method. But programming isn't about playing Doom and Quake. If you're looking for an adrenaline rush try bungee jumping.
125 compilations for a trivial bit of code is not fast. Dynamic? You bet. But not fast.
Oddly, because I suspect Kent Beck is a superprogrammer, the test examples given in the book are exactly like the ones we see dysfunctional programmers creating for their unit tests. None check boundary conditions, like the overflow that any factorial routine is bound to produce for even rather small inputs.
When a problem occurs he says: "Rather than apply minutes of suspect reasoning, we can just ask the computer by making a change and running the tests." Yikes! What if the change seems to work, but in actuality masks some deeper problem? He seems to advocate removing thinking from programming, a very dangerous proposition.
This is a fast world: fast food, drive-through liquor stores, ATMs on every corner, instantaneous email. But software needs thought. Slow down when you find a problem. Think deeply.
And understand the implications of proposed changes. The alternative is making almost random changes.
That's just glorified hacking.