P.4 Architecture Styles
Recurring forms have been widely observed, even if written for completely different systems. These forms occur often enough that they are worth writing and learning about in their own right. We call these forms architecture styles. (In this book, we usually just say styles.) Styles have implications for architecture documentation and deserve definition and discussion in their own right.
Styles allow one to apply specialized design knowledge to a particular class of systems and to support that class of system design with style-specific tools, analysis, and implementations. The literature is replete with a number of styles, and most architects have a wide selection in their repertoires.
For example, we’ll see that modules can be arranged into a useful configuration by restricting what each one is allowed to use. The result is a layered style that imparts to systems that use it qualities of modifiability and portability. Different systems will have a different number of layers, different contents in each layer, and different rules for what each layer is allowed to use. However, the layered style is abstract with respect to these options and can be studied and analyzed without binding them.
For another example, we’ll see that client-server is a common architecture style. The elements in this style are clients, servers, and the protocol connectors that depict their interaction. When used in a system, the client-server style imparts desirable properties to the system, such as the ability to add clients with little effort. Different systems will have different protocols, different numbers of servers, and different numbers of clients each can support. However, the client-server style is abstract with respect to these options and can be studied and analyzed without binding them.
Some styles are applicable in every software system. For example, every system is decomposed into modules to divide the work; hence, the decomposition style applies everywhere. Other examples of “universal styles” are uses, deployment, and work assignment. Some styles occur only in systems in which they were explicitly chosen and designed in by the architect: layered, service oriented, and multi-tier, for example.
Choosing a style, whether it’s one covered in this book or somewhere else, imparts a documentation obligation to record the specializations and constraints that the style imposes and the characteristics that the style imparts to the system. We call this piece of documentation a style guide. The obligation to document a style can usually be discharged by citing a description of the style in the literature: this book, for example. If you invent your own style, however, you should write a style guide for it because it will help you and your peers to apply that style in other systems.
No system is built exclusively from a single style. On the contrary, every system can be seen to be an amalgamation of many different styles. Some (such as decomposition and work assignment) occur in every system, but in addition to these, systems can exhibit a combination of one or more “chosen” styles as well.
Even restricting our attention to component-and-connector styles, it’s possible for one system to exhibit several styles in the following ways:
- Different “areas” of the system might exhibit different styles. For example, a system might use a pipe-and-filter style to
process input data but route the result to a database that is accessed by many elements. This system would be a blend of pipe-and-filter
and shared-data styles. Documentation for this system would include (1) a pipe-and-filter view that showed one part of the
system and (2) a shared-data view that showed the other part. In a case like this, one or more elements must occur in both
views and have properties of both kinds of elements. (Otherwise, the two parts of the system could not communicate with each
other.) These bridging elements provide the continuity of understanding from one view to the next. They likely have multiple interfaces, each providing the mechanisms for letting the element work with other elements in each of the views to which it belongs. The filter/database
connector in Figure P.2 is an example.
Figure P.2 A system combining a pipe-and-filter style with a shared-data style. The “filter/database connector” is a bridging element.
- An element playing a part in one style may itself be composed of elements arranged in another style. For example, a service
provider in an SOA system might, unknown to other service providers or its own service users, be implemented using a multi-tier
style. Documentation for this system would include an SOA view showing the overall system, as well as a multi-tier view documenting
that server, as illustrated in Figure P.3.
Figure P.3 A system combining two styles. Here a service provider is composed internally in a multi-tier style.
- Finally, the same system might simply be seen in different lights, as though you were looking at it through filtered glasses. For example, a system featuring a database repository, as in Figure P.4, may be seen as embodying either a shared-data style or a client-server style. The glasses you choose will determine the style that you “see.”
In the last case, your choice of style-filtered glasses depends, once again, on the uses to which you and your stakeholders intend to put the documentation. For instance, if the shared-data style is more easily understood by the stakeholders that will consume that view, you might choose it. If you need the perspective afforded by more than one style, however, you have a choice. You can document the corresponding views separately, or you can combine them into a single view that is, roughly speaking, the union of what the separate views would be.
P.4.1 Three Categories of Styles
Although no fixed set of views is appropriate for every system, broad guidelines can help us gain a footing. Architects need to think about their software in three ways simultaneously:
- How it is structured as a set of implementation units
- How it is structured as a set of elements that have runtime behavior and interactions
- How it relates to nonsoftware structures in its environment
Each style we present in this book falls into one of these three categories:
- Module styles
- Component-and-connector (C&C) styles
- Allocation styles
When we apply a style to a system, the result is a view. Module views document a system’s principal units of implementation. C&C views document the system’s units of execution. And allocation views document the relations between a system’s software and nonsoftware resources of the development and execution environments.