by Asim Jalis
I went to a talk by Peter Spiro today, who works on the Microsoft
SQL Server.
One of the interesting things he talked about was the layered
architecture. The idea is that you build your system in layers.
Note this is not the same as object-oriented design. The rule is
that each layer can only make calls into the layer below it. It
may not call layers above it. And it also cannot skip a layer and
call a layer two layers below it. It can only communicate with
the layer directly below it.
Each layer creates a layer of abstraction. As you move higher and
higher in the program stack the layers of abstraction increase
and new concepts become obvious and easy to express.
A clean layered architecture allows you to rip out a layer and
rewrite it when the need for this arises. The dependence between
the layers is so constrained that rewriting a layer poses no risk
of instability to the rest of the system.
A layered architecture is also easy to test. You test each one of
the layers. You unit-test a layer by replacing the layer below it
with stubs and the layer above it with the test driving code.
Object-oriented design tends to produce components that are
organized in a web or a mesh with lots of edges connecting
components to each other. The system does not naturally layer
just because it is designed in an object-oriented way.
The other place I have seen this emphasis on layers is in COBOL
programming. COBOL programmers prefix all their routines with
numbers. This naturally leads to layering. The main routines are
1000-SOME-NAME, 2000-SOME-NAME, etc. 1000 calls 1100, 1200, 1300.
1100 calls 1110, 1120, etc.
The call tree is extremely structured. The program is organized
into a tree and each subroutine can only call its children. This
is even more restrictive than a layered approach, but it has the
same flavor.
The basic idea of layering and of the COBOL calling pattern is to
control complexity by restricting who can call whom. In object
oriented programs anyone can call anyone, which leads to web-like
networks.
The general idea here is that the topology of the call tree can
be used to bring manageability to a large software system.
Also, these approaches might not be mutually contradictory. At
different levels different approaches might make sense. For
example, at the lowest level of individual lines of code, the
code is likely to be procedural and tightly coupled. Above this
you might have subroutines and objects. These in turn could be
organized into layers of abstraction.