Immerse into good design principles

This document outlines principles of good design for software. Since the topic is extremely wide, I focus in on the principles and abstractions of the topic. It is not an epiphany, but a collection of thoughts from my experience within design put into words. First, what is good design?

It would be obvious to say that a "good design - solves the problem". Perhaps one could even elaborate to saying "a good design - solves the problem elegantly".
However, analyzing it a little more, one could be solving one problem but introducing others.
From a coding stand-point, this is often found later on, after the implementation is done and thought to be working. A good design may also only be good in the given context. Change the context slightly and you are sitting with a lame duck.
What constitutes a good design is perhaps not that straight-forward.

But then what explanation could possibly be better? A good design should "IMMERSE". The principles are:

 

  • AgIle
    to be agile is to alleviate the stress of change.
  • Minimal
    is a design that is small, efficient and elegant.
  • Maintainable
    is an easily maintainable design and implementation.
  • Environmental
    is to be friendly to the environment, not pollute.
  • Reachable
    must be a reachable, attainable goal.
  • Solving
    must solve the problems it set out to solve.
  • Extensible
    is to allow extensibility to solve other problems later.

An Ag(i)le Design

"... alleviates the stress of change"


Traditionally, flexibility has always had a costly side. (but is it not more costly to change a rigid design?) Modern computing is composed of languages, methodologies and trade-mark patterns, that make it easy to "hard-code", to make things "fixed". We have "contracts" and of course we "bind" to databases. We all know how inflexible databases are for change, and our code that relies on it. Just the terminologies we invent suggest rigid structures, with others including interface contracts, frameworks, procedures, patterns and all the rest you can think of.

On the other side of the fence, being "agile" is actually costly. It usually takes longer to design and implement. Agile code, whether it's being dynamic or extensible, the methods we have, cause us to write code that has these overheads.

An Agile Design (I am not refering to Agile Methodologies):
  • uses abstraction as a technique to make things common.
  • utilizes Design Patterns that facilitate change and extension
  • allows change to occur without affecting the core structure
  • thinks of itself as an iteration before change occurs (ie. changes will come next, so design with the expectation)
  • separates areas that change and those that don't into disctinct artifacts
  • utilizes whitebox and blackbox designs effectively and within the correct area.
  • facilitates the other design principles

Minimal Design

".... is a design that is small, efficient and elegant"

The minimal approach is applied to many areas of the design.

A minimal design:
  • is one that tries to create a small architectural footprint.
  • abstracted terminology is kept to a minimum.
  • finds the core expression of the solution.
  • avoids mess, clutter and distractions.
  • keeps it simple.
  • implementation is minimally categorized.
  • uses other design artifacts (as long as those artifacts maintain the same principles)

Maintainable Design

"... is an easily maintainable design and implementation"

This is often an overlooked area as most are concerned with providing the solution, rather than what it would be like to maintain and code later.

Developers are extremely resistant to large amounts of repetitive work, or maintaining large hard blocks of code, and so should we all.

A maintainable design:


Environmental Design

"... is to be friendly to the environment, not pollute"
An evironmentally friendly design is one that does not affect it's surroundings in a negative way.

An Environmental design:
  • must obey the design philosophy surrounding it.
  • should always try to extend existing designs positively and not pollute it.
  • does not pollute existing code, introduce bugs or impact negatively.
  • tries to not repeat itself or existing artifacts.
  • does not pollute the minimal and maintainable design principles

Reachable Design

"... must be a reachable, attainable goal "

A reachable design, must be reachable with respect to , "time to design", "time to implement", "time to test" and "time to deploy"

A reachable design:

  • is not overly complex.
  • provides a solution to budget.
  • attainable by those who will implement it.
  • implementable by the implementors' knowledge or requires very small learning curve

Solving Design

"... must solve the problems it set out to solve"

A good or bad design is usually determined via its ability in solving the problems it intended to solve.

However, it should not introduce other problems either.

A Solving Design:
  • solves the initial problems.
  • does not introduce new problems.
  • should not envelope the problem so tightly that it cannot be agile enough to solve future ones
  • solves problems from all angles
  • is a long-lasting solve

Extensible Design

"... is to allow extensibility to solve other problems later"

The extensibility of the solving design, is a major part to the longevity of a solve.

The design should be flexible enough within it's own design to allow future customizations.

An Extensible Design:

  • allows future problems the use of the design artifacts that solve today's' problem
  • allows customization of the solution

Conclusion

In order to evaluate a design effectively one also requires time and the ability to learn from their innaccuracies. The principles outlined here are to be used in collaboration. Not all principles may be required at one time, however the more of them you have the better your design will be.