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
- 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 ...
- A framework is not a class library which a programmer dips into whenever a
subroutine is needed.
- The major drawback of the class library approach is that it does not define
an overall structure for an application.
- A framework is a complete application which derives its functionality by
calling programmer-written code.
- A framework calls user-supplied routines, instead of the other way around.
- A framework defines a domain's "worldview" (i.e. a comprehensive conception
or apprehension of the world), and then provides flex points whereby a programmer
can customize the framework in order to implement his/her application.
- It is possible to design a framework that encapsulates all flow of control, leaving
to the programmer only the decisions regarding what state to save and how to
"do" and "undo" commands or tasks.
- A framework is reusable within a narrow domain. It is not all things to
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).