Design Perfume – The sweet smells of quality

Bob Martin wrote about smells that are signs of bad designs. While it’s convenient to have a vocabulary to describe problems, that’s only part of the picture if we want better designs. With a vocabulary for good designs we can more easily identify the strengths in our work and build on them, and we can structure our thinking about the work of others and bring the good back to our own work.

Good design shouldn’t be terra incognita, let’s have some sign posts to guide us in the right direction.

So here are my corrollaries to Bob Martin’s design smells – Julian’s design perfume:

Supple – System is easy to change (not Rigid)

  • Examples: adding new modules, alternate implementations, substitute technologies, additional processing, new functionality, clearer design and refactoring.

Resilient – Problems and their solutions are localised (not Fragile)

  • Failures don’t bring whole systems down
  • Failures don’t introduce bad data
  • Bad data doesn’t propagate
  • The consequences of failure make sense given the causes
  • Technologies are used in obvious and limited scopes
  • Dependencies on specific configurations are localised
  • No significant effects come from accidental patterns of use

Re-usable – Fits in anywhere it might be useful (not Immobile)

  • Any dependencies should make sense
  • Configuration and maintenance should be proportionate:
    • Easy to figure out
    • Sensible defaults
    • Updates should seem relevant and not a burden
  • Reuse should add clarity:
    • Making intention and correct use obvious
    • Not introducing too much unused functionality

Enabling – Makes good practices easy (not Viscous)

  • The right information and operations are available:
    • Back doors are hard find or make
    • It’s easy to find what you need
  • Examples:

Appropriately Complex – Reasons for complexity are obvious (no Needless Complexity)

  • Clearly connecting complexity to business needs, and thinking about the complexity reveals important things
  • Complexity is visible up front:
    • No nasty surprises when you start to dig in
    • Complexity hiding shouldn’t produce time-bombs

DRY – Doesn’t require users to repeat themselves (no Needless Repetition)

  • Good default values and reusable configurations
  • Useful state and memory of previous actions
  • No need to code up the same things repeatedly

Transparent – Good code is obvious and easy to understand (not Opaque)

  • It does what it says it does
  • It doesn’t do anything unexpected
  • It matches reasonable expectations

Although these are in many places around the internet, and I do recommend reading Martins’ books, I’ll include his list of smells here:

  • Rigidity – System is hard to change.
  • Fragility – Changes cause the system to break easily and require other changes.
  • Immobility – Difficult to disentangle components that can be reused in other systems.
  • Viscosity – Doing things right is harder than doing things wrong.
  • Needless Complexity – System contains infrastructure that has no direct benefit.
  • Needless Repetition – Repeated structures that should have a single abstraction.
  • Opacity – Code is hard to understand.