Layered OO System Architecture & Why Dip Is Errant

From: Universe (no email)
Date: 09/23/04


Date: Wed, 22 Sep 2004 20:30:59 -0400

Extended Discussion On Layered OO System Architecture
And Why Dip Is Errant
---------------------------------------------

SCREENS, LIBRARIES AND APPLICATIONS
The various architectural concepts discussed to this point may be
given life, and tied together by an example given by Bjarne
Stroustrup, the creator of C++ OO programming language. The example is
about layers, and "writing a program for geometric shapes on a
screen".[13]
Stroustrup states that such a program would "naturally consist of
three parts", or layers:
Screen Manager
Shape Library
Application program
He notes that "Typically, the parts are written by different people in
different organizations and at different times. The parts are
typically written in the order they are presented, with the added
complication that the designers of a lower level have no precise idea
of what their code will eventually be used for." [14]
This underscores the key point that the existence, and operation of
system layers should not depend on the existence, and operation of
higher layers. A system layer is able to compile, and link
independently of higher system layers when the elements of the layer
depend only upon the same or lower, not higher, layers to compile and
link. If we allowed layers to rely on higher layers, to compile and
link, as some advocate, we would not be able to build and operate
lower layers before the higher ones were constructed. This is clearly
against the spirit of what Stroustrup is getting at above.
While lower layers can exist regardless of the physical existence of
higher level modules, or clients, it's often the case that the
external interface as well as the internal implementation of a lower
layer primarily depends on the responsibilities the lower layer must
fulfill to serve the operational needs of levels that will, or
currently do exist above it. Lower layers are often constructed in
anticipation of being used by higher layer clients; generally that
will be clients in the higher layer immediately adjacent to the lower
layer.
A major reason lower levels are built in a way which does not depend
on the physical existence of any one specific higher level to execute
is so that they may support a variety of higher level clients - each
lower level has the widest scope possible for reuse. If a lower layer
physically only depends on lower levels to execute, it makes it
possible for the layer to serve a broader array of upper level needs
and applications. For example a Screen Manager layer should be able to
provide services for a Text writing library, as well as a Mathematical
formula writing library, and not solely a Shape library.
One reason lower levels should typically have abstract interfaces is
to be able to accommodate a variety of future clients which the lower
level often has no specific knowledge about. Using an abstract
interfaces makes it easier to change a lower level to accommodate new
higher layer clients - generally by adding new classes under the
abstract interface. In addition to the fact that in some languages,
abstract interfaces[15] help to reduce compilation and linking
(physical) dependencies between higher and lower system layers.
Having each layer use abstract interfaces, and be physically dependent
only on lower layers to execute encourages the reuse of higher layers.
Doing these things allows for the existence of many independent,
pre-existing lower level foundations upon which we can place our high
level policy. Reuse of higher layer code can be realized even while
lower layers are able to execute independent of higher layers.

LOW LEVELS, HIGH LEVELS AND ABSTRACT INTERFACES
Here we will deal with an area of misunderstanding. Some claim that
classes which are abstract interfaces are a system's "higher level
policy" and that classes which implement abstract interfaces are "low
level details".[16] In large part this stems from their practice of
doing one or more of the following:
Failure to address a software project in a holistic manner
Primarily approaching system design from the inside out - from the
inside out of a layer, class, object, and groups of same.
Primarily approaching system design from the bottom up
It is true that abstract interfaces specify "what" (policy) as opposed
to "how" (implementation). Yet from an overall layered system
perspective, not all abstract interfaces specify the policy of the
system's highest layers, and not all implementation classes implement
the system's lowest layers.
Abstract interfaces exist in an architecture's lowest levels and these
can hardly be said to be the higher level policy of a system. That is
if higher level policy is taken as the overall nature, sweep, and
thrust of how the system is used as a complete totality. For example
we may accept that the highest level policy of a spreadsheet
application is bond trading.
High level bond trading policy is built on the basis of the layered
architecture of the spreadsheet as a complete software system, which
includes its having a number crunching engine. While the layer the
number crunching engine resides in may have an abstract interface,
that abstract interface is not the "high level" policy of bond
trading.
While it is true that for every layer, abstract interfaces will be the
interface of that layer to layers above it, and are therefore in a
kind of sub-layer above implementation classes of that layer, it is
also the case that viewing the system as a whole, it is actually the
next and further higher up layers that are "high level" with respect
to a layer. What is "higher level" to a layer is not the sub-layer of
abstract interfaces within it, but the totally different layers above
it in the system architecture.
To equate abstract interfaces with "high level policy" is to
mistakenly equate policy only with the highest levels of a layered
architecture. It is ignoring the fact that policy and implementation
exist within every level of a layered system.
In fact, abstract interfaces of a layer can be viewed as phantoms of
the layer's concrete implementation classes. Whereas concrete classes
actually do something, abstract interfaces represent the commonality
of a related group, or set of concrete "doer" classes within the same
layer.
Abstract interfaces concentrate the common essence of a hierarchy of
concrete server classes, and reside in the same layer, or level as the
concrete "doer" classes. Such concentration of commonality exists in
"all" levels of a system's architecture. The purpose of the abstract
interface class is to allow a single service to have many, or variable
forms of implementation. Among other things this allows different
kinds of clients to access the same service point in a layer.
Every layer has its concrete "doer" classes as well as "concentrator"
abstract interfaces. So the inheritance dependency of concrete server
classes on abstract interfaces is not "lower level details" depending
on "higher level policy", but simply same level "how", or "doer"
classes depending on same level "what", or "concentrator" classes for
interface adherence. "Higher level policy" from an overall bond
trading system perspective is a policy like when to sell, not the
policy that every abstract interface has at every layer in the bond
trading system from top to bottom. While the number crunching engine
has an abstract interface, that interface is not like the high level
policy having to do with when to sell bonds.

Excerpted from:
OO Layered Architecture And Subsystems (OOLAS)
by Elliott Coates, Methods & Tools, 1996
   Mainstream OO developers find that discovering and
implementing objective domain abstractions as the core
of high level design is optimal for system architecture
in virtually every aspect - time, effort, complexity
reduction, complexity management,intuitiveness,
preparation for future up scaling, flexibility when
modifying the software due to changes in the domain.
   Many of the benefits result from major units of abstraction
in the high level software architecture being aligned
and corresponding with those in the domain.
   There is an ease in implementing use cases as flowing
around and through the same abstractions in software as
they do for business processes. Also the potential for
reusability of abstractions and relationships is maximized,
etc and so on, ad infinitum.



Relevant Pages

  • Re: How to start with OOP?
    ... "OO Layered Architecture and Subsystems" by Elliott Coates ... when physically - compilation and link wise - each layer of a system depends ... Using an abstract interfaces makes it ... foundations upon which we can place our high level policy. ...
    (comp.object)
  • Re: dip Notions 2 Major Errors
    ... systems to where details do *not* depend upon higher layer policy. ... HIGH LEVELS AND ABSTRACT INTERFACES ... and not all implementation classes implement ...
    (comp.object)
  • Re: dip Notions 2 Major Errors
    ... *not* depend upon higher layer policy. ... A system layer is able to compile, ... HIGH LEVELS AND ABSTRACT INTERFACES ... exist within every level of a layered system. ...
    (comp.object)
  • DIP: Upside Down SW Engieering
    ... ~ the way to achieve lower level detail code physically depending upon ... higher level policy code is to have ... generally takes place WITHIN an individual layer. ... Using an abstract interfaces makes it ...
    (comp.object)
  • Re: graph of behavior - was Re: State vs. Data (was Re: Fans of Template Method with protected varia
    ... It is true that abstract interfaces specify "what" (policy) as opposed ... High level bond trading policy is built on the basis of the layered ... While it is true that for every layer, ...
    (comp.object)