On the newly founded EmergentDesign list MichaelFeathers asks for examples of where failing to plan for distribution makes it difficult to add later. That has not been my experience. I will instead recount how WyCash (the first xp project) acquired distribution through a series of evolutionary steps, none easy, but none made harder by work done before.
WyCash was initially designed as a save-when-finished application. I checked with the company founders to make sure this was ok before joining. They pointed out that their customers were currently using excel which had exactly this behavior.
Within weeks of joining the company I found myself working on failure-proofing the application by writing deltas to a change log that would be automatically replayed on restart after failure. Customers would sometimes forget to save before turning off their computers and never noticed a difference.
A slight variation on this was cooked up when the first customer asked to run two copies of the program cooperatively. Each copy read the other's change log and thus stayed in sync. One was dubbed the master and it was the one that saved.
We now had to get careful about updating stale information in windows. Our logic was to check for applicable changes when returning to open windows and conditionally refreshing them. This resolved an ambiguity that we'd had as long as we'd had multiple windows.
We soon generalized our scheme to more than two users. At this point we added a checkout mechanism to coordinate workflow.
Our change log machinery (from step 2) began to take noticeable time. Profiling showed that it spent most of its time hashing to reconcile identity issues. We pushed this code into a primitive.
We were now getting requests to run the program at transaction volumes that exceeded our confidence in this machinery. We forked a parallel project to explore high-volume implementations. This project stayed suitably current by absorbing the mainline source deltas when convenient.
We converted our product to high-volume. We replaced the cross reading of change logs with reading and writing hunks from a database. We redesigned our serialization format so as to avoid all of the hash lookups we'd tried to speed in step 6. A guiding principle was now to expose just enough of our schema to the database so that it could do its log-N retrieval, but not so much that we would have to tell it about our regular business driven schema evolution.
We eventually abandoned the checkout style workflow by making all our windows transaction-aware. This completed our incremental conversion from single-user to client-server.
We reported our enthusiasm for this incremental approach in a 1992 OOPSLA experience report.
I wouldn't exactly call this emergence since each step was towards a destination we could imagine in advance. (In the four year life of the project we did have several frameworks emerge, much to our surprise.) This list will be interested to know that we did take smaller steps than most designers assume necessary, that the work we did built on past work without any sense of going backwards, and that a robust set of regression tests stood by us throughout the evolution. -- WardCunningham
I was wondering, do you think that you would have ended up with a different design if someone asked for cooperative work prior to fault tolerance? -- MichaelFeathers
Good question. I don't know the answer. Although each step we did take was purposeful, we never planned out the sequence of steps in advance. To answer your question I would have to relive the experience, not dry lab an alternate plan. (Intuition tells me we would have come out with something different, but still ok.) -- Ward