Software architecture seems to be primarily useful in providing an intermediate level of discourse about a system. The components and their connectors provide units of discourse that are smaller than the system, so that the system's requirements can be (implicitly) expressed and discussed in terms of the interactions of these units. At the same time, for a system large enough that simply talking about it at the level of code and code units is not enough, it provides a way to plan and evaluate the design of the system, filling in the conceptual gap between the level of code and the level of requirements.
Figure 2. Component with
provided and required interfaces
Like any module, a component is characterized by the interface it provides (its provided interface) and the interfaces it requires in order to implement its provided interface (its required interfaces).
Each architectural style is characterized by a pattern of connection between each component and the ones that provide its required interfaces.
Architectural styles help a designer organize a system architecture coherently, and help others to understand the architecture. Most systems use a combination of architectural styles, either with different styles for different portions of the architecture, or with two or more patterns of connection among overlapping sets of components, with each pattern corresponding to a different architectural style.
Figure 3. Hierarchical architecture
In this style, the interface of the system is provided by a single component (the Main Component in Figure 3). Some components implement their interfaces with the help of subcomponents; no subcomponent contributes to more than a single parent component. The connectors are typically function or method calls.
In a layered architecture, components are arranged in layers, ordered from lowest to highest, such that each layer only interacts with the one below it (providing its required interfaces) and the one above it (to which it provides required interfaces). The provided interface of the top layer is the provided interface of the system.
Figure 4. Layered architecture (two equivalent views)
The two diagrams in Figure 4 are equivalent. In both cases, Layer 2 provides the interface for the entire system. Layer 1 is inaccessible except to Layer 2, and Layer 0 is inaccessible except to Layer 1. Layer 0's required interfaces are provided by the underlying run-time environment.
Figure 5. Protocol stacks
An important subtype of layered architectures is a stacks architecture, such as is exhibited by the Internet Protocol Suite for TCP/IP. Two stacks simulate communication at each level, although in fact communication only occurs between the lowest levels, the Layer 0s.
In the diagram, each Layer 2 provides an interface for communicating with the other stack through its Layer 2 interface. At this layer, it appears to the user of Layer 2 that the communication is occurring at that level. However, each Layer 2 requires the Layer 1 interface to perform the necessary communication. At this layer also, it appears to the user of Layer 1 that the communication is occurring at that level. However, each Layer 1 requires the Layer 0 interface to perform the necessary communication. This can continue through as many layers as needed to provide the desired characteristics. The two Layer 0 components are actually in communication with each other.
Figure 6. Client-server architecture utilizing two servers
In a client-server architecture, one component, the server, provides an interface that other components, the clients, connect to as needed to request the service provided by the server.
The set of clients is often variable, and the connections are commonly made only as needed. There may be several servers providing the same services, in which case a client may connect to any, and may look up a server in some kind of directory in order to locate an appropriate one; clients may be directed to whichever server is least busy, in order to balance the load and provide fastest service.
Figure 7. Pipe-and-filter architecture
A pipe-and-filter architecture utilizes components that are filters: they take a sequence of inputs and produce a sequence of processed outputs from it. The outputs of each filter become the inputs of the next filter in the pipeline. The system may rearrange the filters in the pipeline at run time, substituting, adding, or deleting filters to achieve different results.
A typical application of this style is image, audio, or other signal processing. Unix command line scripts often incorporate chains of commands (filters), such as grep PAT|sort|uniq for extracting lines matching , sorting them, and discarding repetitions.