Tuesday, August 31, 2004

Layered Architecture

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.