[prev in list] [next in list] [prev in thread] [next in thread] 

List:       extremeprogramming
Subject:    RE: Continual design vs. Up-front design (Was: [XP] Pragmatic Pro
From:       Steven Gordon <sagordon () asu ! edu>
Date:       2003-03-28 16:49:55
[Download RAW message or body]

It would seem that "hard" retrofitting depends on having implemented the
system using a language/platform/framework that at least adequately supports
the unanticipated feature.  If so, it behooves us to do just enough up-front
project scoping with the customer to allow us to apply our experience and
knowledge to suggest the language/platform/framework that will least inhibit
adding the most likely unanticipated features.

-----Original Message-----
From: Jim Little [mailto:jlittle@wgz.com]
Sent: Friday, March 28, 2003 1:49 AM
To: extremeprogramming@yahoogroups.com
Subject: Continual design vs. Up-front design (Was: [XP] Pragmatic
Programmers on XP)


Martin Fowler wrote:
> Jim Little wrote:
>> Having done "hard" retrofits several times, I strongly disagree.  I've
>> retrofitted code with "hard" features three times now: security,
>> transactions, and internationalization.  Each time I was modifying good
code
>> that had zero prior design for the feature in question.  In each case,
the
>> retrofit was easy.
>
>What you reported here is very interesting, but I'd love to get more
>details. Is this something you think you could elaborate on further?

Sure.  I'm not sure what information you're looking for, so I'll just add
some random thoughts about why I think this worked.  Let me know what you're
interested in and I'll go into more detail.

First, I've had the fortune of doing several non-trivial greenfield systems.
By "non-trivial," I mean projects involving teams of four or more
programmers and at least three months to develop.  All of the retrofits
involved greenfield systems.  I'm working on my first significant migration
of legacy code to XP now, so I can't comment on those kinds of problems yet.

The security retrofit took place on a JDK 1.1 system.  The project had been
under development for about four months by a team of four people at that
point.  We had done up-front requirements and design, but the security
requirement was a surprise.  (The up-front requirements gathering failed
utterly.  Weeks after final delivery, the key requirements donor said, "I
wanted it to be a web program, not a Windows program."  This was after he
had participated in feature prioritization meetings, seen the prototype and
signed the requirements doc filled with screen shots.  The two most
important features, security and reporting, were identified as "next
version" features.  Total requirements failure.)

The transaction retrofit took place on a JDK 1.2 web project.  The project
had been under development for about, um, eight months?  The team
fluctuated, but call it five or six people.  Transactions were something I
had expected to come up eventually, but had purposefully ignored as an
experiment with XP.  (Database connection pooling is something else I left
out as an experiment.  That was added, trivially, in a day, about three
months into the project.  A year later, we replaced the defective
third-party connection pooling code with our own.  That took a pair about
two days because there was only one method that dealt directly with
connections.  It would have been much harder if the connection code had been
spread throughout the system, as it was in the beginning of the project.)

The internationalization retrofit took place on that same JDK 1.2 web
project.  The project had been under development for about ten months and
was now about eight people in two teams.  We were separated by a single time
zone: six of us in one state and two of us in another.  Internationalization
was a brand new feature, not at all planned for, but the code was very good
at that point.

There's another "hard" retrofit that I'd forgotten to mention.  I added
internationalization to another web project last year.  A completely
different project (only two developers, only a few months old, written in
C#) but developed with XP.  Internationalizing that project was harder than
the first one, mostly because the code wasn't as good.  Still, it only took
the two of us a week, maybe two.  I don't remember.  Most of the cost
stemmed from not having much centralization, which was largely due to
learning how to design with ASP.NET.  Looking at the direction the design
took over the following weeks, I can confidently say that adding
internationalization later would have been cheaper.

There were two common factors on these projects: Java-like platforms (JDK
1.x and .NET 1.0) and me.  The platforms provided good OO constructs and had
fairly rich standard libraries.  That wasn't much a factor in the security
and transaction retrofit, but certainly helped in the two
internationalization cases.  (Part of the reason the C# internationalization
effort was more difficult was that its support wasn't as mature as Java's.)

In all cases, I was the most experienced OO developer on the team.  As a
result, the coding style strongly reflected my prejudices.  You could argue
that the success is a result of something I'm unconciously doing, not a
result of XP design principles.

The bottom line is this: On all the projects I've run, the design has been
at its worst in the beginning.  That's because I don't really understand the
design space yet.  As I work on the code, I understand its needs and
limitations better.  Ideas form, crystalize, and become obvious.  I
refactor.  The code gets better over time, not worse.  That web project,
which lasted a year or so, was the best code I've ever seen.  In the
beginning, though, it was terrible.  Really screwy persistence architecture,
which was the result of inexperience.  (The result of overdoing an up-front
design after reading your Analysis Patterns book.  :)  Not that I blame
you!)  There's more about that project in my XP Universe paper, "Up-Front
Design Versus Evolutionary Design in Denali's Persistence Layer."

The fact that, on my projects at least, XP means design gets better over
time, not worse, leads me to two conclusions:

* The less design you add now, the less legacy design baggage you'll have
next month.
* The later you can wait to add a hard design feature, the easier and better
it will be.

I've gone from doing intensive design up front, to some design up front, to
very little.  Now I actively avoid it.  I still find myself designing more
than I need to, and I'm often humbled by realizations that I overdid it when
I look back a few months later.

That big web project, for example, could have accomplished much much more if
I had just started with a direct connection to the database and simple text
dumps, rather than a fancy object-oriented architecture.  There was never
any significant business logic added to that app, but I was convinced that I
needed to manage complexity.  We spent months dealing with object-relational
persistence mismatch when we didn't need a domain model at all.  When I
created my up-front design, though, I didn't know that, and no amount of
design work -- or even requirements work -- would have made that clear.  I
wasn't ready to hear it.  (There's more about that project in my XP Universe
paper, "Up-Front Design Versus Evolutionary Design in Denali's Persistence
Layer.")

The big question for me is whether this is just for experts or if any
project can do it.  I don't know the answer to that.  I think you need
XP-style teamwork and collective code ownership.  At least one person on the
team should have all of: an aggressive stance toward eliminating duplicated
code, the capability to differentiate good design from bad design, a
flexible approach to experimenting with design improvements, discipline to
apply big refactorings over time, and the ability to get the team to follow
his lead.

One last thought: I think most people would agree that ease of adding
features depends on how well your design *today* supports it.  The question
is whether up-front design, continual design (via refactoring), or some
combination of both is the best way to achieve that.  My controversial
answer is that *only* continual design should be used and that up-front
design should be avoided.  That position is a 180 degree reversal from how I
felt ten years ago.  It's a reversal based on experimentation and
observation over the course of lots of non-trivial, team-based projects...
but it's still only one person's experience.

Still, it's enough for me to recommend that other people try it.  Then
report back!  We need more experience reports and less speculation.

Jim


To Post a message, send it to:   extremeprogramming@eGroups.com

To Unsubscribe, send a blank message to:
extremeprogramming-unsubscribe@eGroups.com

ad-free courtesy of objectmentor.com 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ 



[Non-text portions of this message have been removed]


To Post a message, send it to:   extremeprogramming@eGroups.com

To Unsubscribe, send a blank message to: extremeprogramming-unsubscribe@eGroups.com

ad-free courtesy of objectmentor.com 

Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/ 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic