Design is all about constructing an abstract processing machine. Something that exists only in a world created by the mind. This machine will have some collection of functional, operational and performance characteristics.
The machine consists of parts, discrete elements that perform particular roles required to support the functional, operational and performance characteristics.
A design should be pure. It may or may not be easily understood depending upon the body of knowledge used in its construction. For example, a design intended to be distributed will contain many subtleties and patterns that most are not familiar with.
The challenge, of course, is to make this abstract machine a reality, create a physical realisation of our abstract processing machine.
During this process of creation it is important we continue to honour the structures in the design. For, if we do not, we create a gap between design and physical reality such that it can be difficult to relate one to the other. Over time these gaps will multiply and widen, such that the physical realisation of the abstract machine no longer looks anything like the original design.
When gaps develop, there will be problems of traceability as one can no longer relate what is being done in the physical realisation to the design. Knowledge retention becomes problematic as the design can no longer be annotated and maintained for reference. The code and build system are now the only truth, containing structures that have been eroded and become grey, ill-defined. A “big ball of mud” develops that no one adequately understands. Knowledge is held in the heads of various people and scattered in code comments and notes on bits of paper.
It becomes harder and harder to reason about the behaviour of the physical realisation impeding speed of evolution. This manifests as reduced development speed or slow resolution of operational issues in production amongst other things.
There are a collection of things we can do to inhibit the onset of this death spiral including:
- Develop and retain a naming convention that fits with the nouns and verbs used in the design.
- Ensure that deployment onto physical machinery is an intuitive mapping that fits the inter-relatedness of components in the design. This compels the design to express constraints in respect of locality and methods of communication. It must also define failure modes and recovery protocols. This may require creation of further layers of abstraction atop physical machinery e.g. lookup mechanisms and remote access constructs.
- Considered selection of supporting infrastructure that works with the design rather than forcing compromises such as false separations of data or code, fractures in naming conventions, tight coupling where the design requires the opposite or introduction of behaviours that interfere with desired performance characteristics.
- Look for situations where the physical realisation is complicated by the design. When this happens, some re-design is natural but care must be taken to ensure that this is not occurring because of inappropriate technology choice.
Of course, nothing is perfect and some compromises must be made to bring these abstract machines into reality. Nevertheless too many compromises bring on the death-spiral so it is important to carefully consider those made and limit the number that exist at any moment in the lifetime of the physical realisation.