Traditional application layering has its roots in real-time/embedded applications, particularly operating systems. Such layering isolated detailed functionality (e.g., the processing of network protocols) under an interface that provided generic access for multiple applications. Structured Programming added layers to the general application development toolkit. At the same time the notion of a subject matter was developed so that a layer represented detailed functionality that was cohesive.
Because object technology is largely about abstractions, it is not surprising that the view of layering has further evolved in that context. Thus the notion of levels of abstraction is simply a more sophisticated view of layering that accounts for the key abstraction characteristics of knowledge and behavior. Paying attention to levels of abstraction is important to the consistency within OO applications.
There are two views of the notion of level of abstraction. One is the common one that correlates strongly with the amount of detail. When we think fo something as abstract, we think of it as generic and unspecialized. Thus the notion of Vehicle is much more general than the notion of Honda Accord. The second view of abstraction is the notion of essence or intrinsic qualities that are unique to an entity or a grtoup of similar entities.
Both views come into play when forming a Package Diagram. We organize the diagram vertically in order of decreasing abstraction in the layers or subsystems. This reflects the association of the amount of detail with abstraction. This is similar to traditional techniques where complexity is managed by decomposing high-level, overall, general responsibilities into low-level, narrowly defined, specific responsibilities. If only behavior is considered when doing this, we have classice functional decomposition.
In OO development, though, the decomposition is based upon much more than just behavior. We abstract entities in terms of both knowledge and behavior in equal measure. In addition, we use abstraction to extract the essence of the entity that is relevant to the problem. It is this second view that causes us to diverge from the simple one-dimensional model of layering. Thus it is possible to have subject matters that reflect the same level of detail but are about quite different things.
This second view is closely allied to subject matters because subject matters are necessarily about different things. However, level of abstraction in this sense is a bit more subtle. It is about the sorts of things that a subject matter knows or does. Often this is reflected in abstracting a paradigm from the subject matter. For example, in a GUI the dominant paradigm is Window and Control. If we wish to represent a problem space entity for display in a GUI we should abstract it in terms of that paradigm. In contrast, the accounting view of the world is dominated by Account and Transaction. So an Account entity with a Balance property in the accounting subject matter might be represented as a Widnow instance for display that had an associated Control instance for the balance property.
One simple example of this sort of thinking is the software for a bank’s ATM machines. The software to actually control the ATM machine itself is quite different than the software used to manage accounts in the bank or the network software used to transmit messages between the ATM and the bank. In addition the networking software that allows them to communicate is quite different than both. Traditional layering would yield a diagram such as:
[ATM Controller] [Accounting] | | | | [.................. Network.................]
where the ATM software and the bank’s accounting software were connected through a layer of network software.
This makes it clear that the ATM software and the bank’s accounting software have quite different subject matters but it doesn’t capture the idea that the ATM software is a service of the bank’s accounting software. In practice the bank accounting software defines the information it needs from customers (account number, etc.) and what customer requests (withdrawal, etc.) it will honor. In that context the ATM is nothing but a service (i.e., simply an interface to the customer). In UML we could capture this in a subsystem Diagram such as:
[ATM Controller] <----------- [Accounting] | | | | | | +----------> [Network] <-----+
where the arrows represent relationships between a client (stem) and a service (arrowhead). The bracketed entities are now Subsystrems in the sense of a UML Package Diagram.
While syntactically correct the figure does not capture a very important aspect of application structure. It doesn’t capture the fact that the ATM software has no business dealing with an Account class of any flavor. The ATM lives at a very different level of abstraction where it simply moves data back and forth between the hardware and the network port while reacting to message types. Unlike the bank’s accounting software, it does not have to have any understanding of the semantics of the data. It should not even know that the bank’s accounting software exists on the other side of the network port.
So the ATM Controller software deals with the processing at a much more detailed level than the accounting software. In addition, it operates with an entirely different paradigm than the other two. The bank's accounting software deals with the high-level semantics of accounts, customers, and transcations. The ATM Controller deals primarily with hardware control and moving message back and forth between the network port and the ATM hardware. Because it constructs the messages it sends, it operates at a semantically more sophisticated level than the network software whose operations are primitive by comparision.
The network software also deals with message and hardware, but in a very different way. The ATM Controller is dominated by the card reader, cash dispenser, display, keyboard, and envelope processor hardware in its local environment. The network software deals routers, domain servers, ports, and distributed protocols. More important, it processes messages on a pass-through basis with no concern at all about content while the ATM Controller's main function is to encode and decode messages. So each type of software deals with a different paradigm and thinks (abstracts) about the world differently.
One can correct this by providing a vertical ordering of the levels of abstraction in the subsystem Diagram, as in:
+------------ [Accounting] | | | | V | [ATM Controller] | | | | V +-------------> [Network]
Now the diagram accurately reflects the levels of abstraction. This will become an important visual cue when it is time to allocate requiremetns to subsystems.
Caution: this is a superficial solution with limited practical value because it does not describe how the levels of abstraction are different. That needs to be done in supplementary model documentation that describes the various subsystems. It is extremely important to the overall application’s internal consistency to ensure that everyone on the development team understands the level of abstraction of each subsystem.