Iterative Incremental Development of Global InfrastructureSource: email@example.com
John Favaro wrote:
[...] it seems like some parts of the overall system are "global infrastructure". They have to be implemented before any functionality for any use case can be provided. And even those which are not entirely of that nature would not seem to be amenable to "piece-wise" implementation as a part of implementing each successive use case - but rather should be designed and implemented with a view to all system functionality.
Yet incremental development organized along use cases is recommended and apparently very successful. I figure that we're just not looking at it the right way. What is the right way?
Robert C. Martin replied:
There is a tradeoff to be made here, and it's not an easy one to make.
On the one hand, it is true that a significant amount of infrastructure may be necessary before certain use cases can be implemented.
On the other hand, it is also sometimes true that those use cases could be implemented with stubbed/throwaway infrastructure.
Whether you develop the infrastructure before the use cases, or whether you stub the infrastructure so that you can develop the use cases depends upon a number of factors.
The dangers of implementing the use cases first and stubbing the architecture are that you waste the time spent writing the stubs, and that the users don't get to see certain aspects of the behavior (i.e. full multiuser operation, or full high bandwidth operation) because the stubs aren't capable.
The benefit of writing the use cases with stubbed infrastructure is that you get a better appreciation for what the infrastructure must do. Also users get to see the use cases early.
The benefit of writing the infrastructure early and delaying the use cases is that the users get to see the use cases working at full functionality; and that you don't waste time on writing the stubs.
In the end, I prefer a compromise situation. I like to write some stubs to mimic some of the infrastructure and then write some use cases to give the users an early view. Then I replace a few stubs, write a few use cases, replace a few more stubs, write a few more use cases, etc.
BTW, though we've been bandying the term 'use-case' around; the iterative approach is not actually based upon use cases. Rather it is based upon units of functionality that can be implemented incrementally. This is sometimes partitioned the way use cases are, but not always, and not necessarily. You may decide to implement portions of use cases, or groups of use cases in every iteration. The important thing to remember about an iteration is that it should always show something new to the user.
Alistair Cockburn suggested to treat the infrastructure itself as a deliverable:
Who's a user and what counts as functionality? The people coding up use cases are users of the infrastructure. There is no contradiction in building a global infrastructure incrementally, and many people do it regularly.
You do some architecture and some stubbing and some skeleton code and some minimum feature support, and there is increment 2 (increment 1 is a "hello, partner" or "echo" type of program that shows that the global pieces can at least talk to each other). Then you build up from there, adding features, replacing stubs, or replacing simplistic solutions with subtle ones. At some point, the use case implementors will stop using their stubbed system ("shunts" is the term I use) and start using the global infrastructure.
With OO techniques, the infrastructure team should be able to keep evolving the infrastructure only occasionally disturbing the use case team.
Infrastructure development and use case development are going on simultaneously. It's not as though you do one first and then the other. You do them both, and both incrementally.
Alistair Cockburn, Surviving Object-Oriented Projects: A Manager's Guide
David Harvey, Evolutionary Delivery
Alistair Cockburn, Using "V-W" Staging to Clarify Spiral Development
Todd Cotton, Evolutionary Fusion