In spite of the interest in software architecture as a field of research, there is little agreement among researchers as to what exactly should be included in the definition of architecture. In many cases, this has led to important aspects of architectural design being overlooked by past research. This chapter defines a self-consistent terminology for software architecture based on an examination of existing definitions within the literature and my own insight with respect to network-based application architectures. Each definition, highlighted within a box for ease of reference, is followed by a discussion of how it is derived from, or compares to, related research.
A software architecture is an abstraction of the run-time elements of a software system during some phase of its operation. A system may be composed of many levels of abstraction and many phases of operation, each with its own software architecture. |
At the heart of software architecture is the principle of abstraction: hiding some of the details of a system through encapsulation in order to better identify and sustain its properties [117]. A complex system will contain many levels of abstraction, each with its own architecture. An architecture represents an abstraction of system behavior at that level, such that architectural elements are delineated by the abstract interfaces they provide to other elements at that level [9]. Within each element may be found another architecture, defining the system of sub-elements that implement the behavior represented by the parent element's abstract interface. This recursion of architectures continues down to the most basic system elements: those that cannot be decomposed into less abstract elements.
In addition to levels of architecture, a software system will often have multiple operational phases, such as start-up, initialization, normal processing, re-initialization, and shutdown. Each operational phase has its own architecture. For example, a configuration file will be treated as a data element during the start-up phase, but won't be considered an architectural element during normal processing, since at that point the information it contained will have already been distributed throughout the system. It may, in fact, have defined the normal processing architecture. An overall description of a system architecture must be capable of describing not only the operational behavior of the system's architecture during each phase, but also the architecture of transitions between phases.
Perry and Wolf [105] define processing elements as "transformers of data," while Shaw et al. [118] describe components as "the locus of computation and state." This is further clarified in Shaw and Clements [122]: "A component is a unit of software that performs some function at run-time. Examples include programs, objects, processes, and filters." This raises an important distinction between software architecture and what is typically referred to as software structure: the former is an abstraction of the run-time behavior of a software system, whereas the latter is a property of the static software source code. Although there are advantages to having the modular structure of the source code match the decomposition of behavior within a running system, there are also advantages to having independent software components be implemented using parts of the same code (e.g., shared libraries). We separate the view of software architecture from that of the source code in order to focus on the software's run-time characteristics independent of a given component's implementation. Therefore, architectural design and source code structural design, though closely related, are separate design activities. Unfortunately, some descriptions of software architecture fail to make this distinction (e.g., [9]).
A software architecture is defined by a configuration of architectural elements--components, connectors, and data--constrained in their relationships in order to achieve a desired set of architectural properties. |
A comprehensive examination of the scope and intellectual basis for software architecture can be found in Perry and Wolf [105]. They present a model that defines a software architecture as a set of architectural elements that have a particular form, explicated by a set of rationale. Architectural elements include processing, data, and connecting elements. Form is defined by the properties of the elements and the relationships among the elements -- that is, the constraints on the elements. The rationale provides the underlying basis for the architecture by capturing the motivation for the choice of architectural style, the choice of elements, and the form.
My definitions for software architecture are an elaborated version of those within the Perry and Wolf [105] model, except that I exclude rationale. Although rationale is an important aspect of software architecture research and of architectural description in particular, including it within the definition of software architecture would imply that design documentation is part of the run-time system. The presence or absence of rationale can influence the evolution of an architecture, but, once constituted, the architecture is independent of its reasons for being. Reflective systems [80] can use the characteristics of past performance to change future behavior, but in doing so they are replacing one lower-level architecture with another lower-level architecture, rather than encompassing rationale within those architectures.
As an illustration, consider what happens to a building if its blueprints and design plans are burned. Does the building immediately collapse? No, since the properties by which the walls sustain the weight of the roof remain intact. An architecture has, by design, a set of properties that allow it to meet or exceed the system requirements. Ignorance of those properties may lead to later changes which violate the architecture, just as the replacement of a load-bearing wall with a large window frame may violate the structural stability of a building. Thus, instead of rationale, our definition of software architecture includes architectural properties. Rationale explicates those properties, and lack of rationale may result in gradual decay or degradation of the architecture over time, but the rationale itself is not part of the architecture.
A key feature of the model in Perry and Wolf [105] is the distinction of the various element types. Processing elements are those that perform transformations on data, data elements are those that contain the information that is used and transformed, and connecting elements are the glue that holds the different pieces of the architecture together. I use the more prevalent terms of components and connectors to refer to processing and connecting elements, respectively.
Garlan and Shaw [53] describe an architecture of a system as a collection of computational components together with a description of the interactions between these components--the connectors. This model is expanded upon in Shaw et al. [118]: The architecture of a software system defines that system in terms of components and of interactions among those components. In addition to specifying the structure and topology of the system, the architecture shows the intended correspondence between the system requirements and elements of the constructed system. Further elaboration of this definition can be found in Shaw and Garlan [121].
What is surprising about the Shaw et al. [118] model is that, rather than defining the software's architecture as existing within the software, it is defining a description of the software's architecture as if that were the architecture. In the process, software architecture as a whole is reduced to what is commonly found in most informal architecture diagrams: boxes (components) and lines (connectors). Data elements, along with many of the dynamic aspects of real software architectures, are ignored. Such a model is incapable of adequately describing network-based software architectures, since the nature, location, and movement of data elements within the system is often the single most significant determinant of system behavior.
A component is an abstract unit of software instructions and internal state that provides a transformation of data via its interface. |
Components are the most easily recognized aspect of software architecture. Perry and Wolf's [105] processing elements are defined as those components that supply the transformation on the data elements. Garlan and Shaw [53] describe components simply as the elements that perform computation. Our definition attempts to be more precise in making the distinction between components and the software within connectors.
A component is an abstract unit of software instructions and internal state that provides a transformation of data via its interface. Example transformations include loading into memory from secondary storage, performing some calculation, translating to a different format, encapsulation with other data, etc. The behavior of each component is part of the architecture insofar as that behavior can be observed or discerned from the point of view of another component [9]. In other words, a component is defined by its interface and the services it provides to other components, rather than by its implementation behind the interface. Parnas [101] would define this as the set of assumptions that other architectural elements can make about the component.
A connector is an abstract mechanism that mediates communication, coordination, or cooperation among components. |
Perry and Wolf [105] describe connecting elements vaguely as the glue that holds the various pieces of the architecture together. A more precise definition is provided by Shaw and Clements [122]: A connector is an abstract mechanism that mediates communication, coordination, or cooperation among components. Examples include shared representations, remote procedure calls, message-passing protocols, and data streams.
Perhaps the best way to think about connectors is to contrast them with components. Connectors enable communication between components by transferring data elements from one interface to another without changing the data. Internally, a connector may consist of a subsystem of components that transform the data for transfer, perform the transfer, and then reverse the transformation for delivery. However, the external behavioral abstraction captured by the architecture ignores those details. In contrast, a component may, but not always will, transform data from the external perspective.
A datum is an element of information that is transferred from a component, or received by a component, via a connector. |
As noted above, the presence of data elements is the most significant distinction between the model of software architecture defined by Perry and Wolf [105] and the model used by much of the research labelled software architecture [1, 5, 9, 53, 56, 117-122, 128]. Boasson [24] criticizes current software architecture research for its emphasis on component structures and architecture development tools, suggesting that more focus should be placed on data-centric architectural modeling. Similar comments are made by Jackson [67].
A datum is an element of information that is transferred from a component, or received by a component, via a connector. Examples include byte-sequences, messages, marshalled parameters, and serialized objects, but do not include information that is permanently resident or hidden within a component. From the architectural perspective, a "file" is a transformation that a file system component might make from a "file name" datum received on its interface to a sequence of bytes recorded within an internally hidden storage system. Components can also generate data, as in the case of a software encapsulation of a clock or sensor.
The nature of the data elements within a network-based application architecture will often determine whether or not a given architectural style is appropriate. This is particularly evident in the comparison of mobile code design paradigms [50], where the choice must be made between interacting with a component directly or transforming the component into a data element, transferring it across a network, and then transforming it back to a component that can be interacted with locally. It is impossible to evaluate such an architecture without considering data elements at the architectural level.
A configuration is the structure of architectural relationships among components, connectors, and data during a period of system run-time. |
Abowd et al. [1] define architectural description as supporting the description of systems in terms of three basic syntactic classes: components, which are the locus of computation; connectors, which define the interactions between components; and configurations, which are collections of interacting components and connectors. Various style-specific concrete notations may be used to represent these visually, facilitate the description of legal computations and interactions, and constrain the set of desirable systems.
Strictly speaking, one might think of a configuration as being equivalent to a set of specific constraints on component interaction. For example, Perry and Wolf [105] include topology in their definition of architectural form relationships. However, separating the active topology from more general constraints allows an architect to more easily distinguish the active configuration from the potential domain of all legitimate configurations. Additional rationale for distinguishing configurations within architectural description languages is presented in Medvidovic and Taylor [86].
The set of architectural properties of a software architecture includes all properties that derive from the selection and arrangement of components, connectors, and data within the system. Examples include both the functional properties achieved by the system and non-functional properties, such as relative ease of evolution, reusability of components, efficiency, and dynamic extensibility, often referred to as quality attributes [9].
Properties are induced by the set of constraints within an architecture. Constraints are often motivated by the application of a software engineering principle [58] to an aspect of the architectural elements. For example, the uniform pipe-and-filter style obtains the qualities of reusability of components and configurability of the application by applying generality to its component interfaces -- constraining the components to a single interface type. Hence, the architectural constraint is "uniform component interface," motivated by the generality principle, in order to obtain two desirable qualities that will become the architectural properties of reusable and configurable components when that style is instantiated within an architecture.
The goal of architectural design is to create an architecture with a set of architectural properties that form a superset of the system requirements. The relative importance of the various architectural properties depends on the nature of the intended system. Section 2.3 examines the properties that are of particular interest to network-based application architectures.
An architectural style is a coordinated set of architectural constraints that restricts the roles/features of architectural elements and the allowed relationships among those elements within any architecture that conforms to that style. |
Since an architecture embodies both functional and non-functional properties, it can be difficult to directly compare architectures for different types of systems, or for even the same type of system set in different environments. Styles are a mechanism for categorizing architectures and for defining their common characteristics [38]. Each style provides an abstraction for the interactions of components, capturing the essence of a pattern of interaction by ignoring the incidental details of the rest of the architecture [117].
Perry and Wolf [105] define architectural style as an abstraction of element types and formal aspects from various specific architectures, perhaps concentrating on only certain aspects of an architecture. An architectural style encapsulates important decisions about the architectural elements and emphasizes important constraints on the elements and their relationships. This definition allows for styles that focus only on the connectors of an architecture, or on specific aspects of the component interfaces.
In contrast, Garlan and Shaw [53], Garlan et al. [56], and Shaw and Clements [122] all define style in terms of a pattern of interactions among typed components. Specifically, an architectural style determines the vocabulary of components and connectors that can be used in instances of that style, together with a set of constraints on how they can be combined [53]. This restricted view of architectural styles is a direct result of their definition of software architecture -- thinking of architecture as a formal description, rather than as a running system, leads to abstractions based only in the shared patterns of box and line diagrams. Abowd et al. [1] go further and define this explicitly as viewing the collection of conventions that are used to interpret a class of architectural descriptions as defining an architectural style.
New architectures can be defined as instances of specific styles [38]. Since architectural styles may address different aspects of software architecture, a given architecture may be composed of multiple styles. Likewise, a hybrid style can be formed by combining multiple basic styles into a single coordinated style.
Some architectural styles are often portrayed as "silver bullet" solutions for all forms of software. However, a good designer should select a style that matches the needs of the particular problem being solved [119]. Choosing the right architectural style for a network-based application requires an understanding of the problem domain [67] and thereby the communication needs of the application, an awareness of the variety of architectural styles and the particular concerns they address, and the ability to anticipate the sensitivity of each interaction style to the characteristics of network-based communication [133].
Unfortunately, using the term style to refer to a coordinated set of constraints often leads to confusion. This usage differs substantially from the etymology of style, which would emphasize personalization of the design process. Loerke [76] devotes a chapter to denigrating the notion that personal stylistic concerns have any place in the work of a professional architect. Instead, he describes styles as the critics' view of past architecture, where the available choice of materials, the community culture, or the ego of the local ruler were responsible for the architectural style, not the designer. In other words, Loerke views the real source of style in traditional building architecture to be the set of constraints applied to the design, and attaining or copying a specific style should be the least of the designer's goals. Since referring to a named set of constraints as a style makes it easier to communicate the characteristics of common constraints, we use architectural styles as a method of abstraction, rather than as an indicator of personalized design.
In parallel with the software engineering research in architectural styles, the object-oriented programming community has been exploring the use of design patterns and pattern languages to describe recurring abstractions in object-based software development. A design pattern is defined as an important and recurring system construct. A pattern language is a system of patterns organized in a structure that guides the patterns' application [70]. Both concepts are based on the writings of Alexander et al. [3, 4] with regard to building architecture.
The design space of patterns includes implementation concerns specific to the techniques of object-oriented programming, such as class inheritance and interface composition, as well as the higher-level design issues addressed by architectural styles [51]. In some cases, architectural style descriptions have been recast as architectural patterns [120]. However, a primary benefit of patterns is that they can describe relatively complex protocols of interactions between objects as a single abstraction [91], thus including both constraints on behavior and specifics of the implementation. In general, a pattern, or pattern language in the case of multiple integrated patterns, can be thought of as a recipe for implementing a desired set of interactions among objects. In other words, a pattern defines a process for solving a problem by following a path of design and implementation choices [34].
Like software architectural styles, the software patterns research has deviated somewhat from its origin in building architecture. Indeed, Alexander's notion of patterns centers not on recurring arrangements of architectural elements, but rather on the recurring pattern of events--human activity and emotion--that take place within a space, with the understanding that a pattern of events cannot be separated from the space where it occurs [3]. Alexander's design philosophy is to identify patterns of life that are common to the target culture and determine what architectural constraints are needed to differentiate a given space such that it enables the desired patterns to occur naturally. Such patterns exist at multiple levels of abstraction and at all scales.
As an element in the world, each pattern is a relationship between a certain context, a certain system of forces which occurs repeatedly in that context, and a certain spatial configuration which allows these forces to resolve themselves.
As an element of language, a pattern is an instruction, which shows how this spatial configuration can be used, over and over again, to resolve the given system of forces, wherever the context makes it relevant.
The pattern is, in short, at the same time a thing, which happens in the world, and the rule which tells us how to create that thing, and when we must create it. It is both a process and a thing; both a description of a thing which is alive, and a description of the process which will generate that thing. [3]
In many ways, Alexander's patterns have more in common with software architectural styles than the design patterns of OOPL research. An architectural style, as a coordinated set of constraints, is applied to a design space in order to induce the architectural properties that are desired of the system. By applying a style, an architect is differentiating the software design space in the hope that the result will better match the forces inherent in the application, thus leading to system behavior that enhances the natural pattern rather than conflicting with it.
An architectural viewpoint is often application-specific and varies widely based on the application domain. ... we have seen architectural viewpoints that address a variety of issues, including: temporal issues, state and control approaches, data representation, transaction life cycle, security safeguards, and peak demand and graceful degradation. No doubt there are many more possible viewpoints. [70]
In addition to the many architectures within a system, and the many architectural styles from which the architectures are composed, it is also possible to view an architecture from many different perspectives. Perry and Wolf [105] describe three important views in software architecture: processing, data, and connection views. A process view emphasizes the data flow through the components and some aspects of the connections among the components with respect to the data. A data view emphasizes the processing flow, with less emphasis on the connectors. A connection view emphasizes the relationship between components and the state of communication.
Multiple architectural views are common within case studies of specific architectures [9]. One architectural design methodology, the 4+1 View Model [74], organizes the description of a software architecture using five concurrent views, each of which addresses a specific set of concerns.
I include here only those areas of research that define software architecture or describe software architectural styles. Other areas for software architecture research include architectural analysis techniques, architecture recovery and re-engineering, tools and environments for architectural design, architecture refinement from specification to implementation, and case studies of deployed software architectures [55]. Related work in the areas of style classification, distributed process paradigms, and middleware are discussed in Chapter 3.
Most early research on software architecture was concentrated on design methodologies. For example, object-oriented design [25] advocates a way to structure problems that leads naturally to an object-based architecture (or, more accurately, does not lead naturally to any other form of architecture). One of the first design methodologies to emphasize design at the architectural level is Jackson System Development [30]. JSD intentionally structures the analysis of a problem so that it leads to a style of architecture that combines pipe-and-filter (data flow) and process control constraints. These design methodologies tend to produce only one style of architecture.
There has been some initial work investigating methodologies for the analysis and development of architectures. Kazman et al. have described design methods for eliciting the architectural aspects of a design through scenario-based analysis with SAAM [68] and architectural trade-off analysis via ATAM [69]. Shaw [119] compares a variety of box-and-arrow designs for an automobile cruise control system, each done using a different design methodology and encompassing several architectural styles.
Shaw [117] advocates the development of architectural handbooks along the same lines as traditional engineering disciplines. The object-oriented programming community has taken the lead in producing catalogs of design patterns, as exemplified by the "Gang of Four" book [51] and the essays edited by Coplien and Schmidt [33].
Software design patterns tend to be more problem-oriented than architectural styles. Shaw [120] presents eight example architectural patterns based on the architectural styles described in [53], including information on the kinds of problems best suited to each architecture. Buschmann et al. [28] provide a comprehensive examination of the architectural patterns common to object-based development. Both references are purely descriptive and make no attempt to compare or illustrate the differences among architectural patterns.
Tepfenhart and Cusick [129] use a two dimensional map to differentiate among domain taxonomies, domain models, architectural styles, frameworks, kits, design patterns, and applications. In the topology, design patterns are predefined design structures used as building blocks for a software architecture, whereas architectural styles are sets of operational characteristics that identify an architectural family independent of application domain. However, they fail to define architecture itself.
Reference models are developed to provide conceptual frameworks for describing architectures and showing how components are related to each other [117]. The Object Management Architecture (OMA), developed by the OMG [96] as a reference model for brokered distributed object architectures, specifies how objects are defined and created, how client applications invoke objects, and how objects can be shared and reused. The emphasis is on management of distributed objects, rather than efficient application interaction.
Hayes-Roth et al. [62] define domain-specific software architecture (DSSA) as comprising: a) a reference architecture, which describes a general computational framework for a significant domain of applications, b) a component library, which contains reusable chunks of domain expertise, and c) an application configuration method for selecting and configuring components within the architecture to meet particular application requirements. Tracz [130] provides a general overview of DSSA.
DSSA projects have been successful at transferring architectural decisions to running systems by restricting the software development space to a specific architectural style that matches the domain requirements [88]. Examples include ADAGE [10] for avionics, AIS [62] for adaptive intelligent systems, and MetaH [132] for missile guidance, navigation, and control systems. DSSA emphasize reuse of components within a common architectural domain, rather than selecting an architectural style that is specific to each system.
Most of the recent published work regarding software architectures is in the area of architecture description languages (ADL). An ADL is, according to Medvidovic and Taylor [86], a language that provides features for the explicit specification and modeling of a software system's conceptual architecture, including at a minimum: components, component interfaces, connectors, and architectural configurations.
Darwin is a declarative language which is intended to be a general purpose notation for specifying the structure of systems composed of diverse components using diverse interaction mechanisms [81]. Darwin's interesting qualities are that it allows the specification of distributed architectures and dynamically composed architectures [82].
UniCon [118] is a language and associated toolset for composing an architecture from a restricted set of component and connector examples. Wright [5] provides a formal basis for specifying the interactions between architectural components by specifying connector types by their interaction protocols.
Like design methodologies, ADLs often introduce specific architectural assumptions that may impact their ability to describe some architectural styles, and may conflict with the assumptions in existing middleware [38]. In some cases, an ADL is designed specifically for a single architectural style, thus improving its capacity for specialized description and analysis at the cost of generality. For example, C2SADEL [88] is an ADL designed specifically to describe architectures developed in the C2 style [128]. In contrast, ACME [57] is an ADL that attempts to be as generic as possible, but with the trade-off being that it doesn't support style-specific analysis and the building of actual applications; rather, its focus is on the interchange among analysis tools.
Abowd et al. [1] claim that architectural styles can be described formally in terms of a small set of mappings from the syntactic domain of architectural descriptions (box-and-line diagrams) to the semantic domain of architectural meaning. However, this assumes that the architecture is the description, rather than an abstraction of a running system.
Inverardi and Wolf [65] use the Chemical Abstract Machine (CHAM) formalism to model software architecture elements as chemicals whose reactions are controlled by explicitly stated rules. It specifies the behavior of components according to how they transform available data elements and uses composition rules to propagate the individual transformations into an overall system result. While this is an interesting model, it is unclear as to how CHAM could be used to describe any form of architecture whose purpose goes beyond transforming a data stream.
Rapide [78] is a concurrent, event-based simulation language specifically designed for defining and simulating system architectures. The simulator produces a partially-ordered set of events that can be analyzed for conformance to the architectural constraints on interconnection. Le Métayer [75] presents a formalism for the definition of architectures in terms of graphs and graph grammars.
This chapter examined the background for this dissertation. Introducing and formalizing a consistent set of terminology for software architecture concepts is necessary to avoid the confusion between architecture and architecture description that is common in the literature, particularly since much of the prior research on architecture excludes data as an important architectural element. I concluded with a survey of other research related to software architecture and architectural styles.
The next two chapters continue our discussion of background material by focusing on network-based application architectures and describing how styles can be used to guide their architectural design, followed by a survey of common architectural styles using a classification methodology that highlights the architectural properties induced when the styles are applied to an architecture for network-based hypermedia.
[Top] [Prev] [Next] | © Roy Thomas Fielding, 2000. All rights reserved. | [How to reference this work.] |