The #2 Serious Flaw in Extreme Programming (XP)

by Conrad Weisert
© 2002 Information Disciplines, Inc., Chicago

NOTE: This article may be circulated freely as long as the copyright notice is included.

Related articles on this and other web sites
as of October, 2003
Agile Methods and Torpid Programmers
The #1 Serious Flaw in Extreme Programming
Software Reality web site -- articles, book reviews, and experience reports
Book review: An Extreme Programming Book for Non-Extremists

Scope creep and generality

The warning

Just about every article or presentation on extreme programming includes a warning against too much flexibility in program design. XP gurus stress the "YAGNI principle" (you aren't going to need it), pointing out that software developers have been known to fritter away time designing and building extra features ("bells & whistles) that turn out to have little if any value.

"Just build what the users need today and worry about the future in a later iteration" is their advice. Unfortunately, programmers taking that advice are building naively inflexible software components.

The misunderstanding

The problem is that many programmers who take that advice confuse adding fancy features with generalizing scope of applicability at the level of individual components. In many cases it takes little additional effort, if any, to avoid an unreasonable restriction. The infamous "Y2K crisis" is a glaring example: Developers who extended the scope of their date representations beyond the user's immediate need avoided huge costs at almost no upfront expense. They didn't have to implement any additional date functionality or features, just a sensible representation.

Component Completeness and Cohesion

Reusability

For years we've been proclaiming and reporting the huge benefits of reusable components. Using an existing component, whether a single subroutine, a complete object-oriented class, an application "framework", or any other sort of building-block, not only reduces development time but also contributes to operational reliability and manageable future maintenance.

Indeed, many experts believe that among all tools and methodologies, reuse is the single most significant contributor to programming productivity.

When we discourage generality of scope or penalize programmers for going beyond their users' immediate needs, we insure that our projects will rarely if ever contribute new complete, cohesive, and reliable items to our component library. And if our library is full of undocumented fragments having severely limited scopes, we insure that our programmers will rarely if ever draw upon it.

A Simple Example: Money class

Martin Fowler, in defending YAGNI1, has given us a powerful example against it. He posits a Money class in an application that needs to add two amounts of money but doesn't today need to multiply an amount of money by a scalar. With that incomplete class if unitPrice and totalDue are Money objects, then:

This is just unacceptable at an application level, even in the middle of incremental and iterative development. A reasonable application programmer would be irate upon discovering such anomalies.

In a course or textbook on object-oriented programming in C++ we advise our students:

The picture of hordes of class designers violating (in pairs) such common-sense principles is alarming in the Xtreme.

So, how much additional effort would be needed to make our Money complete? Very little. In fact, if we've been serious about building up a library of reusable components, it may actually take less effort to build a reliable complete Money class than to build an ad hoc class fragment.

Money is an instance of a pattern that arises often with numeric data types. Whenever the type has a unit of measure and is closed under addition, the same arithmetic and relational operators are required. We can capture and (in C++ but not Java2) implement that pattern as reusable code for the benefit of programmers building classes such as Money, Distance, or Duration.

Fowler's Money example yields a further demonstration. In our Money class we're going to need either an output-stream operator (C++) or a toString conversion function (Java). We must then choose a default external data representation, e.g. $125,049.95. Our implementation of that function then uses three character constants, the currency symbol ($), the group separator (,), and the decimal point (.). All of them would have to be changed to use our class for, say, Norwegian money. However, it takes very little additional effort to give those constants names, and to use those names instead of the hard-coded values. This is one of the oldest principles of good programming practice, and it's painful to see XP extremists violating it.

The Money class on this web site in C++ and Java illustrates a complete and coherent numeric data type.


1 -- "Is Design Dead?", Software Development Magazine, April, 2001.

2 -- You can do it initially in Java by pasting the pattern into the source code in an editor, but you'll be stuck with dual maintenance in the future if the pattern should be improved or corrected.

Return to IDI home page

Last modified April 10, 2007