Pattern name: Four layer Architecture
Problem:
When designing an object system for a client-server environment, what is the most appropriate way to structure the overall application architecture? How do you structure your system when you have both significant presentation and domain components?
Forces:
When designing the software architecture in a client-server system, you must come up with a way to divide the labor among team members. Your architecture must also be simple enough to be easily explainable to new team members, so they can understand where their work fits.
In looking for an application architecture, many developers have looked to the pioneering ModelViewController (MVC) architecture. However, MVC is not the be-all and end-all of object design. While a proper architecture should address the concerns addressed by MVC, and may trace its descent from MVC, modern software systems must also address issues not covered by classic MVC.
MVC promoted reuse by factoring out the UI widgetry from the domain objects. Modern class libraries derived from MVC have also discovered yet another set of potentially useful and reusable abstractions in separating out the aspect of mediating between views and adapting views to domain models into another set of classes.
However, this still does not address the connection of the domain to the outside world (i.e., object persistency mechanisms, network protocols, etc.). A complete architecture for client-server systems must address these issues as well. Therefore:
Solution:
Factor your application classes into four layers in the following way (see Figure 1: FourLayerArchitecture):
The View layer. This is the layer where the physical window and widget objects live. It may also contain Controller classes as in classical MVC. Any new user interface widgets developed for this application are put in this layer. In most cases today this layer is completely generated by a window-builder tool.
The ApplicationModel layer. This layer mediates between the various user interface components on a GUI screen and translates the messages that they understand into messages understood by the objects in the domain model. It is responsible for the flow of the application and controls navigation from window to window. This layer is often partially generated by a window-builder and partially coded by the developer.
The DomainModel layer. This is the layer where most objects found in an OO analysis and design will reside. Examples of the types of objects found in this layer may be Orders, Employees, Sensors, or whatever is appropriate to the problem domain.
The Infrastructure layer. This is where the objects that represent connections to entities outside the application (specifically those outside the object world) reside. Examples of objects in this layer would include SQLTables, 3270Terminals, SerialPorts, SQLBrokers and the like.
Discussion:
This choice of layers can have many beneficial effects on your application if it is applied in the proper way. First, since the architecture is so simple, it is easy to explain to team members and so demonstrate where each object's role fits into the "big picture".
If a designer is very strict about clearly defining where objects fit within the layers, and the interfaces between the layers, then the potential for reuse of many objects in the system can be greatly increased. A common problem with object designs is that they are too tightly constrained to the limits of the particular application being built. Many novice designers tend to put too much of the logic of an application in the Application Model layer. In this case, there are few, if any, domain objects that are potentially available for reuse in other applications.
Another benefit of this layering is that it makes it easy to divide work along layer boundaries. BobbyWoolf demonstrated how a "layered and sectioned architecture" can be made the basis of a source-code control system. It is easy to assign different teams or individuals to the work of coding the layers in a four-layer architectures, since the interfaces are identified and understood well in advance of coding.
Finally, a four-layer architecture makes it possible to code the bulk of your system (in the domain model and application model layers) to be independent of the choice of persistence mechanism and windowing system.
Sources:
Layering is not a new idea in computer science - AndrewTanenbaum mentions it in conjunction with the OpenSystemsInterconnect seven-layers communications model. Shaw discusses layering as an architectural choice.
GregHendley? first discussed the benefits in portability gained by additional layering in the View and Application Model layers in Smalltalk in an early SmalltalkReport article. KyleBrown first phrased this pattern in print (http://members.aol.com/kgb1001001/Articles/LAYERS/appmod.htm) and further investigated the reasons for applying four-layer architectures for Smalltalk.
Dijkstra's (EwDijkstra) paper on his T.H.E. operating system may have been the first significant and/or popular report on layered systems.
Related Patterns:
A pattern that is closely related to FourLayerArchitecture that is central to the way I view Object Distribution as working is TrimAndFitClient. AlistairCockburn has an interesting variation on this theme that he calls HexagonalArchitecture.
Much More discussion moved to FourLayerArchitectureDiscussion