Reasoning About Software Quality Attributes
Quality attribute requirements such as those for performance, security, modifiability, reliability, and usability have a significant influence on the software architecture of a system. Architects need to understand their designs in terms of quality attributes. For example, they need to understand whether they will achieve deadlines in real time systems, what kind of modifications are supported by their design and how the system will respond in the event of a failure. There are large and thriving attribute communities that study various quality attributes but they each have their own language and sets of concepts. However, architects tend to think in terms of architectural patterns. What the architect needs is a characterization of architectural patterns in terms of factors that affect the various quality attributes so that a software design can be understood in terms of those quality attributes.
In order to reason about architectural patterns in quality attribute terms, we must first precisely characterize the quality attribute requirements and then give examples of how to reason about architectural patterns. We characterize quality attributes using general scenarios and codify architectural as quality attribute design primitives (or attribute primitives). Attribute primitives are an extension of our earlier work on Attribute-Based Architectural Styles.
General Scenarios
In order to be able to analyze and evaluate the quality of any system, we first need to characterize the various quality attribute requirements applicable to the system. Quality attribute scenarios serve this purpose. For the same reason that use cases are essential in determining functional requirements, quality attribute scenarios are used to specify quality attribute requirements. For five important quality attributes (modifiability, performance, availability, security and usability), we have enumerated a collection of quality attribute “general scenarios” that are intended to encompass all of the generally accepted meanings for these quality attribute. A general scenario is in effect a template for generating a specific quality attribute scenario. For example, a modifiability general scenario is:
- The platform on which the system depends is changed. The system must be modified to continue to provide current functionality. The platform change may be a change in hardware including input and output hardware, it could be a change in operating system or it could be a change in COTS middleware included in the system. Existing functionality of the system should remain unchanged.
And a reliability general scenario is:
- An internal component fails. The system is able to recognize a failure of an internal component and has strategies to compensate the fault.
These scenarios are “general” in the sense that they are system independent. Collectively, general scenarios provide a system independent checklist for quality attribute requirements. [Bass 01] presents our initial attempt at a comprehensive list of general scenarios for modifiability, usability, performance, reliability and security.
Attribute Primitives
Just as general scenarios provide a template for specifying quality attribute requirements, quality attribute design primitives are templates for “chunks” of architectural designs that target the achievement of specific quality attribute goals.
Attribute primitives provide building blocks for constructing architectures. However, they are building blocks with a focus on achieving quality attribute goals such as performance, reliability and modifiability goals. Quality attribute design primitives will be codified in a manner that illustrates how they contribute to the achievement of quality attributes. Therefore each attribute primitive will be described not only in terms of their constituent components and connectors, but also in terms of the qualitative and/or quantitative models that can be used to argue how they affect quality attributes.
Consider an example: the client/server attribute primitive. This is collaboration between the providers and users of set of services. The attribute primitive separates one collection of responsibilities (the client’s) from another (the server’s). The consequence of this separation is enhanced modifiability; modifying the implementation of the services or modifying the number of servers providing services is invisible (at least in principle) to the clients. Moreover, the addition of new clients has no effect on the server.
The client/server attribute primitive has modifiability as one focus. When we write up this attribute primitive we will articulate what we mean by “modifiability” by describing various modifiability general scenarios for which the mechanism is well suited and we will make qualitative and/or quantitative arguments as to why it is well suited.
In addition, the effects of client/server on other attribute must also be consider. Separation of computations might improve reliability; and increased network traffic might increase the vulnerability to certain types of security attacks. Each attribute primitive write up highlights possible side effects on other attributes.
In summary each attribute primitive write up will address one or more quality attributes as characterized by one or more general scenarios. It will offer a description of the components, their relationships and properties, as they are relevant to the general scenario and a rationale for why this ensemble contributes to the achievement of the general scenario.
Our intent is to codify a fairly comprehensive set of attribute primitives in a manner that articulates the specific contribution each attribute makes toward the achievement of its attribute goal (or goals) and why. We believe this will provide a very powerful “language” for constructing software architectures that will predictably satisfy quality attribute requirements.