Development as a series of Expansions and Contractions
Software development can be seen as an iterative process where each iteration consists of an Expansion followed by a Contraction.
An Expansion consists in implementing new features as quickly as possible. The focus is exclusively on getting the new features to (somewhat) work. This may be seen as a prototyping of the new features, because they are implemented hastily and thus superficially, but quickly. During an expansion the elements that are not directly observable in the functionality being added may be ignored: elegance, orthogonality, consistency, performance, algorithmic complexity, economic data structures, exception condition handling, error reporting, logging, scalability. An expansion consists in getting it to work as fast as possible, but the quick solution may be a dirty one.
A Contraction conserves the existing features, but cleans up the mess. The code is refactored. The redundant parts are removed. The design is pondered and improved. Design orthogonality, consistency, simplicity, elegance are of paramount importance. The behavior in corner-cases (limit, exceptional situations) is carefully analized and tested. Many bugs are found and fixed. The performance (speed, memory usage, etc.) is measured and improved (profiling). More efficient algorithms replace the naive implementations of the Expansion. During a Contraction no new features are added, the externally observable functionality remains unchanged, but the internals are consolidated.
An Expansion shows the developers where the product can go, it gives them inspiration and trust that the difficulties can be overcome. But during an expansion, as the implementation becomes more and more disorganized, the developers get a sense of uncertainty on the code, of gradually losing the understanding of how the things work, losing grip on the code. Forward progress becomes gradually harder, because building on the now shaky foundation is difficult. These are indications that it’s time for a Contraction.
A Contraction makes the developer feel that the implementation is getting clean, elegant, and solid. The developer re-gains control and trust over the code. The code is becoming smaller, streamlined, beautiful, efficient. On the other hand, the observable functionality of the product doesn’t change, doesn’t progress during the Contraction. The result of the Contraction is a clean, solid and trusty base from which the next Expansion can be attempted.
During the Expansion the developer increases the size of the codebase. During the Contraction, he decreases the size of the code. Thus the work of the developer consists in both adding code (the positive, constructive aspect) and removing code (the destructive aspect). Destructive is meant here in a good sense, like burning the extra fat, cleaning the weeds, removing a tumor or sweeping-out the garbage. And I dare say that removing code, that is re-organising the code in a better way while keeping the functionality essentially unchanged, is harder to master than adding new code.
To somebody not involved in the internals of a project, only the Expansion has visible results. From the external viewpoint, during the Expansion the project grows as new functionality is added, while during the Contraction it looks like nothing is happening. It is tempting to direct the team like this: good, you just finished this Expansion, it’s time to start the next Expansion right ahead. Were developers to follow such advice, they would find it harder and harder to advance as the project becomes disorganized, anarchical, amorphic after a series of Expansions with no Contractions.
And a parallel with the bubble: during an economic expansion, there is an abundance of capital and exuberant growth. But the abundent capital drives both good and not so good enterprises, and the affluent ressources are not used efficiently. A contraction is needed to wipe out the lousy businesses, thus freeing the capital blocked by them, and to urge the remaining business to move to a new level of efficiency. The healthier result forms the base of the next expansion.
November 14th, 2006 at 09:54
Interesting point of view.
It may be considered that it maps onto the Agile methodology, with one Expansion and one Contraction seen as a pair forming an iteration.
One interesting thing in this approach is that the Contraction phase tends to shrink in time, because over the life of a project, patterns that are identified in development are continuously applied in the upcoming Expansion phases, thus minimizing the next Contractions.