OO Levels of Leverage

Here is one (of possibly many) taxonomies for characterizing OO design advise. From lesser to greater granularity, there are: heuristics, principles, patterns. Additionally, frameworks (as understood in the reuse community) are the pinnacle of OO design — the reuse "system" is the center of the solar system, and individual applications are simply the "third rock from the sun".

      Design heuristics ... lower level rules of thumb. Not meant to define hard and fast rules; they serve more as warning mechanisms. The subconscious list of guidelines that seasoned experts might use to evaluate the quality of a design. Here is a list of heuristics by ICON Computing ...
  • Beware the "god" object
  • Anticipate change and localize its effect
  • Don't ask, don't poll
  • Watch for object data bloat
  • Prefer composition over inheritance
  • Avoid parallel case statements
  • Avoid lots of get and set methods
Design principles ... higher level, more general encapsulation of insight. Heuristics could be described as tactical, and principles as strategic. Some possible examples ...
  • All problems can be solved with one more level of indirection.
  • Components should be open for extension, but closed for modification.
  • Policy should be published in an abstract base class, and details should be buried in concrete derived classes.
  • Clients should interact with an abstract base class and should not be surprised when they receive an instance of any derived subclass.
  • A class should define a separate interface (pure abstract base class) for every "role" it is responsible for supporting.

      Design patterns ... the definition, abstraction/generalization, and archiving of successful and popular designs. A pattern captures the same kind of leverage in the OO world as the term "stack" captures in the data structures world. (Stack immediately and implicitly communicates the notion of a LIFO queue with functions like push(), pop(), and is_empty(), that can be used to traverse a hierarchical tree.) Some GoF pattern examples ...
  • Strategy ... encapsulate a "family" of algorithms and make them interchangeable via composition and delegation
  • Template Method ... encapsulate the steps of an algorithm, define the invariant steps in a base class, and make the variable steps configurable through inheritance.
  • Observer ... decouple an independent object from its dependent views so that the number and type of views can vary at run-time.
  • Abstract Factory ... design for portability by abstracting "host platform" and decoupling creation requests.
  • Proxy ... define an extra level of indirection that can provide one or more of the following: lazy initialization, distributed access, protected access, instrumentation/metrics upon access.

Frameworks ... reverse the traditional idea of reuse. Instead of a programmer writing a main program which calls reusable procedures, a programmer instantiates objects from the framework's architecture and then implements methods that the framework will call. A framework is a miniature application complete with dynamic and static standardization. It is a reusable template where the programmer "fills in the blank". Frameworks are specialized for a narrow range of applications because each model of interaction is domain-specific. They are the product of many iterations in design over long periods of time. A list of bullet points ...

Frameworks use abstract classes to define and maintain relationships between objects.
They are often responsible for creating these objects.
The framework client defines his/her application-specific derived classes
(the MyXxx classes above).