Last Modified 5-1-2010
Software EngineeringSoftware Architecture
User Interface Design
Component Based SE
Global Software Development
Software ArchitectureArchitecture Introduction
Software Life Cycle
Architecture Design Decisions
Main Program with Subroutines
Abstract Data Type
Pipes And Filters
Layers Architectural Style
User Interface DesignSeeheim Model
Model View Controller
User Interface Aspects
Human Computer Interaction
IS Mental Models
Interactive System Design
Design Activity Structure
HCI Task Analysis
Component Based SE
Component ModelsComponent Forms
CBSE Development ProcessCBSE System Development
Architectural ApproachesProduct Lines
Description & Communication
Service Oriented Architecture
Software architecture concerns the large-scale structure of software systems. This large-scale structure reflects the early, essential design decisions. The decision process involves negotiating and balancing functional and quality requirements on the one hand and possible solutions on the other hand. Software architecture is not a phase strictly following requirements engineering, but the two are intertwined. In this chapter, we discuss how to design, document, and evaluate software architectures.
A good design is the key to a successful product. Almost 2000 years ago, the architect Vitruvius recorded what makes a design good: durability (firmitas), utility (utilitas), and charm (venustas). These quality requirements still hold, for buildings as well as software systems. A well-designed system is easy to implement, is understandable and reliable, and allows for smooth evolution. Badly designed systems may work at first, but they are hard to maintain, difficult to test, and unreliable.
During the design phase, the system is decomposed into a number of interacting components. The top-level decomposition of the system into major components together with a characterization of how these components interact, is called software architecture. Viewed this way, software architecture is synonomous with global design. There is, however, more to software architecture than mere global design.
This mutual influencing between an architecture and its environment is a cyclical process, known as the Architecture Business Cycle. For example, an architecture yields certain units of work, corresponding to the components distinguished in the architecture. If the same components occur over and over again, expertise will be organized according to the functionality embedded in these components. The development organization may then become expert in certain areas. This expertise then becomes an asset which may affect the goals of the development organization. The organization may try to develop and market a series of similar products in which this expertise is exploited.
Traditional design is inward-looking: given a set of requirements, how can we derive a system that meets those requirements. Software architecting includes negotiating and balancing of functional and quality requirements on one hand, and possible soltuions on the other hand. Balancing requirements also requires that the candidate software architecture is assessed. This is a form of testing.
One of the early definitions of software architecture is:
The architecture of a software system defines that system in terms of computational components and interaction among those components.
A more recent definition is:
The software architecture of a program or computing system is the structure or structures of the system, which comprise software elements, the externally visible properties of those elements, and the relationships among them.
The latter definition reflects, among others, the insight that there may be more than one structure that is of interest. In house construction, we also use different drawings: one for the electrical wiring, one for the water supply, etc. These drawings reflect different structures which are all part of the same overall architecture. We generally observe the architecture through one of these more specific views. The same holds for the software architecture.
In the software architecture, the global structure of the system has been decided upon. This global structure captures the early, major design decisions. Whether a design decision is major or not really can only be ascertained with hindsight, when we try to change the system. Only then will it show which decisions were really important. A priori, it is often not at all clear if and why one design decision is more important than another. For instance, we may decide to separate the user interface from the processing part and store data about books in a flat file in our library system. Both decisions could be important, but need not be. Separating the user interface from the processing part is generally considered good design. If, at a later stage, changes occur, the decision was not all that important, after all. Deciding to use flat files to store data in your library system may turn out to be important if our library grows and we are forced to switch to database storage of data. But again, if no such change occurs, the decision wasn't that important either.
Viewed this way, the architectural design process is about making the important design decisions. Next, these important design decisions need to be documented.
A very active field of research these days is aimed at identifying and describing components at a higher level of abstraction, i.e. above the level of a module or abstract data type. These higher-level abstractions are known as design patterns and software architectural styles (or architectural patterns).
Part of the work in software architecture is aimed at characterizing and classifying these software architectural styles, as well as developing appropriate notations and supporting tools. The ultimage goal is that the resulting abstractions become part of the vocabulary of software engineers, much like abstract data types are already part of that vocabulary.
Today's work in software architecture is broad in scope. Almost any topic in software engineering is being rethought in architectural terms. The discussion in this chapter is focused on how to design, name, document, and assess software architectures.
If software architecture is just global design, we would be selling old wine in new bottles. The design phase is simply split into 2 subphases: architectural, global design, and detailed design. The methods used in these two subphases might be different, but both essentially boil down to a decomposition process, taking a set of requirements as their starting point. Both design phases then are inward looking: starting from a set of requirements, derive a system that meets those requirements.
A proper software architecture phase however has an outward focus as well. It includes negotiating and balancing of functional and quality requirements on one hand, and possible solutions on the other hand. This means requirements engineering and software architecture are not subsequent phases that are more or less strictly separated, but instead they are heavily intertwined. An initial set of functional and quality requirements is the starting point for developing an initial architecture. This initial architecture results in a number of issues that require further discussion with stakeholders. For instance, the envisagd solution may be too costly, integration with already existing systems may be complex, maintenance may be an issue because of a lack of staff with certain expertise, or performance requirements cannot be met. These insights lead to further discussions with stakeholders, a revised set of requirements, and a revised architecture. This iterative process continues until an agreement is reached. Only then will detailed design and implementation proceed.
We thus see important differences between the traditional process models without specific attention to software architecture, and process models which do not pay attention to software architecture:
Design is a problem-solving activity, and as such very much a matter of trial and error. In the presentation of a mathematical proof, subsequent dovetail well into each other and everything drops into place at the end. The actual discovery of the proof was probably quite different. The same holds for the design of software. We should not confuse the outcome of the design process with the process itself. The outcome of the design process is a rational reconstruction of that process. Note that this is precisely the same remark with respect to the outcome of the requirements engineering process.
During design, the system is decomposed into parts that each have a lower complexity than the system as a whole, while the parts together solve the user's problem. The design problem can now be formulated as follows: how to determine this decomposition. There really is no universal method for this. The design process is a creative one, and the quality and expertise of the designers is a critical determinant for its success. Yet, during the course of the years, a number of ideas and guidelines have emerged which may serve us in designing software. These have resulted in a large number of design methods.
In a similar vein, architectural design methods have been developed. A good example is the Attribute Driven Design. The input of the Attribute Driven Design process are the requirements, formulated as a set of prioritized quality attribute scenarios. A quality attribute scenario is a scenario as known from requirements engineering, but whose description explicitly captures quality information.
Attribute Driven Design is described as a topdown decomposition process. In each iteration, one or a few components are selected for further decomposition. In the first iteration, there is only one component, the system. From the set of quality attribute scenarios, an important quality attribute is selected that will be handled in the current refinement step. For instance, in our library system, we may have decided on a first decomposition of the system into three layers:
In the next Attribute Driven Design, we may decide to decompose the presentation layer, and select usability as the quality attribute that drives this decomposition. A pattern is then selected that satisfies the quality attribute. For instance, a data validation pattern may be applied to verify whether data items have been entered correctly. Finally, the set of quality attribute scenarios is verified and refined, to prepare for the next iteration.
Attribute Driven Design gives little guidance for the precise order and kind of refinement steps. This is very much a matter of the architect's expertise. The same rather global support is given by other architecture design methods. The global workflow common to these methods is depicted in Figure 2. At the center, the backlog is depicted. The backlog contains a list of issues to be tackled, open problems, ideas that still have to be investigated and so on. The name derives from Scrum which is an agile method. There, the backlog drives the project. In architecture design projects, the notion of a backlog is usually not represented explicitly. Yet, it is always there, if only in the head of the architect. There are 3 inputs to the backlog:
The context refers to such things as upfront ideas the architect may have, available assets that can be used, constraints set, and the like. Obviously, the requirements constitute another important input. In each stepof the architecting process, one or a few items from the backlog are taken and used to transform the architecture developed so far. The result of this transformation is evaluated, and this evaluation may in turn change the contents of the backlog. New items may be added, items may disappear ro become obsolete, and the priorties of the backlog may change.
Figures 1 & 2 describe the same iterative process (Figure 1 is in the introduction). Whereas the former emphasizes interactions with external parties, the latter emphasizes the architectural design process itself. The latter process model also is more finegrained. Many of the iterations involving one or more items of the backlog, a synthesis step, evaluation of the result and updating the backlog will be done by the architect and not involve the communication with other stakeholders. But once in a while, communication with other stakeholders takes place, and this is the level at which Figure 1 applies.
The architecture design process is very much driven by the architect's experience, much more so than by any of the so-called architecture design methods. An experienced architect knows how to handle a given issue, rather than that some method tells him how to perform a design iteration. The description for methods describing how to perform software design iterations give much more guidance than those for architecture design methods. But this guidance is used by inexperienced designers mostly. Since architecture design is usually done by experienced designers, the amount of guidance given, and needed, is less. Attention then shifts to techniques for documenting the result of the design process: the decisions, their rationale, and the resulting diagram.
If architecture is the set of design decisions, then documenting the architecture boils down to documenting the set of design decisions. This is usually not done, though. We can usually get at the result of the design decisions, the solutions chosen, but not at the reasoning behind them. Much of the rationale behind the solutions is usually lost forever, or resides only in the heads of the few people associated with them, if they are still around.
So the reasoning behind a design decision is explicitly captured. This is tacit knowledge, essential for the solution chosen, but not documented. At a later stage, it then becomes difficult to trace the reasons of certain design decisions. In particular, during evolution one may stumble upon these design decisions, try to undo them or work around them, and get into trouble when this turns out to be costly if not impossible.
It is an illusion to want to document all design decisions. There are far too many of them, and not all of them are that important. And documenting design decisions takes time and effort from the architect, a very busy person. But we may try to document the really important ones.
A design decision addresses one or more issues that are relevant for the problem at hand. There may be more than one way to resolve these issues, so that the decision is a choice from amongst a number of alternatives. The particular alternative selected preferably is chosen because it has some favorable characteristics. That is, there is a rationale for our particular choice. Finally, the particular choice made may have implications for subsequent decision making. Table 1 gives a template for the type of information that is important to capture for each design decision.
Table 2 gives an example of a design decision for our library application. It concerns the choice for a 3-tier architecture, consisting of a presentation layer, a business logic layer, and a data management layer.
Design decisions are often related. A given design decision may constrain further decisions, exclude or enable them, and the like. These relationships between design decisions resemble the kind of relationships that may exist between requirements. And, likewise, the notations and tools used to capture this information are very similar as well. A simple way to structure design decisions hierarchially is in the form of a decision tree. An example of this is given in Figure 3.
A software architecture serves as a vehicle for communication among stakeholders. Example stakeholders are: end users of the anticipated system, security experts, representativies from the maintenance department, owners of other systems that this system has to interface with, software developers, and of course the architect himself. These stakeholders have a stake, but the stakes may differ. End users will be interested to see that the system will provide them with the functionality asked for. Software developers will be interested to know where to implement this functionality. Maintainers want to assure themselves that components are as independent as possible.
In some cases, it may be possible to devise one single architecture representation that serves all these stakeholders. In general, this will not work, though. A specific stakeholder is best served by a representation of the software architecture that highlights his concerns. Another stakeholder is likely to be better served by another representation. Just think of civil engineering, where one representative may highlight the outer appearance, while another highlights construction aspects.
IEEE standard 1471 gives a general structure for software architecture representations. The main elements from this standard are:
So the stakeholder concerns determine which representations, called views, are appropriate for a specific software architecture. Each view has a corresponding viewpoint which gives the syntax of the view, much like a construction drawing has an accompanying description telling what the the glyphs in the drawing mean.
IEEE 1471 does not tell you which viewpoints to use. In essence, it suggests we develop an appropriate set of viewpoints for each separate software architecture. It does have the notion of a library viewpoint, though, a viewpoint that might be useful across different software architectures. A collection of viewpoints that is useful across a wide variety of software architectures fall into three classes:
Of course, you do not have to use all these viewpoints for a single software architecture. Usually, one from each category will suffice. You may, for instance, choose the decomposition, deployment and work-assignment viewpoints. It is also possible to combine viewpoints. In Figure 4 we have combined the decomposition viewpoint and the client-server viewpoint to create a view of our library system. In specific cases, additional architectural views may be helpful or needed. In systems for which the user interface is of critical importance, a separate user-interface view may be developed; in electronic commerce applications, a view highlighting security aspects may come in handy; and so on.
Many organizations have developed their own set of library viewpoints. A well-known set of library viewpoints is known as the 4+1 model. It consists of the following viewponints:
The +1 viewpoint is a set of important use cases. This set of use cases drives the architectural design and serves as glue to connect the other four viewpoints. The 4+1 model is part of the Rational Unified Process development methodology.
The above viewpoints are technical in nature. Often, it is also useful to construct one or more viewpoints which emphasize business concerns. Figure 5 gives a business oriented view of our library system. It addresses three aspects of the architecture:
For each of the three aspects, several alternatives are given, and, for each alternative, the risk, time to market, and cost are indicated. One alternative for each aspect is chosen. These alternatives are connected by curved lines. In this way, a quick overview is obtained. The view is also easy to grasp for non-technical stakeholders.
One interesting theory of problem-solving in the programming domain states that programmers solve such problems using programming plans, program fragments that correspond to stereotypical actions, and rules that describe programming conventions. For example, to compute the sum of a series of numbers, a programmer uses the running total loop plan. In this plan, some counter is initialized to zero and incremented with the next value of a series in the body of the loop. Experts tend to recall program fragments that correspond to plan structures before they recall other elements of the program. This nicely maps onto the idea that knowledge is stored in human memory in meaningful units or 'chunks'.
An expert programmer has at his disposal a much larger number of knowledge chunks than a novice programmer. This concerns both programming knowledge and knowledge about the application domain. Both during the search for a solution and during program comprehension, the programmer tries to link up with knowledge arleady present. As a corollary, part of our education as programmer or software engineer should consist of acquiring a set of useful knowledge chunks.
At the level of algorithms and abstract data types, such a body of knowledge has been accumulated over the years, and has been codified in text books and libraries of reusable components. As a result, abstractions, such as Quicksort, embodied in procedures and abstract data types, such as Stack and Binary Tree, have become part of our vocabulary and are routinely used in our daily work.
The concepts embodied in these abstractions are useful during the design, implementation and maintenance of software for the following reasons:
Design patterns are collections of a few modules, or classes, which are often used in combination, and which together provide a useful abstraction. A design pattern is a recurring solution to a standard problem. The prototypical example of a pattern is the MVC or Model-View-Controller pattern known from Smalltalk. We may view design patterns as micro-architectures.
Two further notions often used in this context are application framework and idiom. An application framework is a semi-finished system which needs to be instantiated to obtain a complete system. It describes the architecture of a family of similar systems. It is thus tied to a particular application domain. The best known examples are frameworks for building user interfaces. An idiom is a low-level pattern, specific to some programming language. For example, the Counted Pointer idiom can be used to handle references to objects dynamically created in C++. It keeps a reference counter which is incremented or decremented when references to an object are added or removed. Memory occupied by an object is freed if no references to that object remain, i.e. when the counter becomes zero. Frameworks and idioms thus offer solutions that are more concrete and language specific than the architectural styles or design patterns.
The work in the area of software architecture and design patterns has been strongly influenced by the ideas of the architect Christopher Alexander, as formulated in his books The Timeless Way of Building and A Pattern Language. The term pattern derives from Alexander's work, and the format used to describe software architectural styles and design patterns is shaped after the format Alexander used to describe his patterns, like alcove, office connection, or public outdoor room. In software engineering, we often draw a parallel with other engineering disciplines, in particular civil engineering. This comparison is made to highlight both similarities, such as the virtues of a phased approach, and differences, such as the observation that software is logical rather than phsyical, which hampers the control of progress. The comparison with the field of architecture is often made to illustrate the role of different views, as expressed in the different types of blueprint produced. Each of these blueprints emphasizes a particular aspect.
The classical field of architecture provides some further interesting insights for software architecture. These insights concern:
Architecture is a formal arrangement of architectural elements. An architectural style abstracts from the specifics of an architecture. The decomposition library system might, for instance, result in architecture consisting of one main program and four subroutines, sharing three data stores. If we abstract from these specifics, we obtain its architectural style, in which we concentrate on the types of its elements and their interconnections.
Viewed in this way, an architectural style describes a certain codification of elements and their arrangements. Conversely, an architectural style constrains both the elements and their interrelationships. For example, the Tudor style describes how a certain type of house looks and also prescribes how its design should look. In a similar vein we may characterize a software architectural style such as, say, the pipes-and-filter style.
Different engineering principles apply to different architectural styles. This often goes hand in hand with the types of material used. Cottage-style houses and high-rise apartments differ in the materials used and the engineering principles applied. A software design based on the abstract types (=material) emphasizes separation of concerns by encapsulating secrets (=engineering principle). A design based on pipes and filters emphasizes bundling of functionality in independent processes.
When selecting a certain style with its corresponding engineering principles and materials, we are guided by the problem to be solved as well as the larger context in which the problem occurs. We cannot build a skyscraper from wooden posts. Environmental regulations may prohibit us from erecting high-rise buildings in rural areas. And, the narrow frontages of many houses on the Amsterdam canals are partly due to the fact that local taxes were based on the number of street-facing windows. Similar problem-specific and context-specific elements guide us in the selection of a software architectural style.
These similarites between classical architecture and software architecture provide us with clues as to what constitutes a software architectural style and what its description should look like.
In his book A Pattern Language, the architect Christopher Alexander presents 253 patterns, ranging in scale from how a city should look down to rules for the construction of a porch. Perhaps his most famous pattern is about the height of buildings:
"There is abundant evidence to show that high buildings make people crazy.
An Alexandrian pattern is not a cookbook, black box recipe for architects, any more than a dictionary is a toolkit for a novelist. Rather, a pattern is a flexible generic scheme providing a solutiong to a problem in a given context. In a narrative form, its application looks like this:
IF you find yourself in <context>, for example <examples>, with <problem>,
The above Four Story Limit pattern may for example be applied in a context where one has to design a suburb. The citation gives some of the reasons for applying this pattern. If it is followed, it will give rise to the application of other patterns, such as those for planning parking lots, the layout of roads, or the design of individiual houses.
A number of well-known software architectural styles are often in a framework that resembles a popular way of describing design patterns. Both the characterization and the framework are framed after Alexander's way of describing patterns. We will use this framework to describe a number of well-known and classic architectural styles. The framework has the following entries:
The order of execution of components is governed by the control structure. The control structure captures how control is transformed during execution.
The choice of components and connectors is not independent. Usually, a style is characterized by a combination of certain types of component and connector, as well as a certain control structure. The system model captures the intuition behind such a combination.
Architectural styles give a rather general description. Variants are specializations which differ from the general style.
Examples are references to real examples of a style. Architectural styles do not stem from theoretical investigations, but result from identifying and characterizing best practice.
Tables 8 through 13 contain descriptions of six well-known architectural styles:
In the main program with subroutines architectural style, the main tasks of the system, are allocated to different components, which are called, in the appropriate order, from a control component. The decomposition is strongly geared towards an ordering of the various actions to be performed with respect to time. The top-level component controls this ordering.
Components in the main program with subroutines type of decomposition often use shared data storage. Decisions about data representations, then, are a mutual property of the components that use the data. We may also try to make those decisions locally rather than globally. In that case, the user does not get direct access to the data structures, but is offered an interface. The data can only be accessed through appropriate procedure or method calls. This is the essence of the Abstract Data Type Architectural Style.
A major advantage of abstract data types over shared data is that changes in data representation and algorithms can be accomplished relatively easily. Changes in functionality, however, may be much harder to realize. This is because method invocations are explicit, hard-coded in the implementation. An alternative is to use the Implicit Invocation Style.
In implicit invocation, a component is not invoked explicitly. Instead, an event is generated. Other components in the system may express their interest in this event by associating a method with it; this method is automatically invoked each time the event is raised. Functional changes can be realized easily by changing the list of events that components are interested in.
Some applications consist of a series of components in which component i produces output which is read and processed by component i+1, in the same order in which it si written by component i. In such cases, we need not explicitly create these intermediate data structures. Rather, we may use the pipe-and-filter method of operation that is well known from UNIX, and directly feed the output of one transformation into the next one. The components are called filters and the FIFO connectors are called pipes.
An important characteristic of this scheme is that any structure imposed on the data to be passed between adjacent filters has to be explicitly encoded in the datastream that connects these filters. This encoding scheme involves decisions which must be known to both filters. The data has to be unparsed by one filter while the next filter must parse its input in order to rebuild that structure. The Achille's heel of the pipes-and-filters scheme is error handling. if one filter detects an error, it is cumbersome to pass the resulting error message through intermediate filters all the way to the final output. Filters must also be able to resynchronize after an error has been detected and filters further downstream must be able to tolerate incomplete input.
The repository style fits situations where the main issue is to manage a richly structured body of information. In the library example in the section on Requirements Engineering, the data concerns such things as the stock of available books and the collection of members of the library. The data is persistent and it is important that it always reflects the true state of affairs. A natural approach to this problem is to devise database schemas for the various types of data in the application and store the data in one or more databases. The functionality of the system is incorporated in a number of, relatively independent, computational elements. The result is a repository architectural style.
Modern compilers are often structured in a similar way. Such a compiler maintains a central representation of the program to be translated. A rudimentary version of that representation results from the first, lexical, phase: a sequence of tokens rather than a sequence of character glyphs. Subsequent phases, sucy as syntax and semantic analysis, further enrich this structure into, for example, an abstract syntax tree. In the end, code is generated from this representation. Other tools, such as symbolic debuggers, pretty-printing programs or static analysis tools, may also employ the internal representation built by the compiler. The resulting architectural style again is that of repository: one memory component and a number of computational elements that act on the repository. Unlike the database variant, the order of invocation of the elements matters in the case of a compiler. Also, different computational elements enrich the internal representation, rather than merely update it.
The repository architectural style can also be found in certain AI applications. In computationally complex applications, such as speech recognition, an internal representation is built and acted upon by different computational elements. For example, one computational element may filter noise, another one builds up phenomes, etc. The internal representation in this type of system is called a blackboard and the architecture is sometimes referred to as a blackboard architecture. A major difference with traditional database systems is that the invocation of computational elements in a blackboard architecture is triggered by the current state of the blackboard, rather than by external inputs. Elements from a blackboard architecture enrich and refine the state representation until a solution is found.
The final example of an architectural style is the layered architectural style. A prototypical instance is the ISO Open System Interconnection Model for network communication. It has seven layers:
The bottom layer provides basic functionality. Higher layers use the functionality of lower layers. The different layers can be viewed as virtual machines whose 'instructions' become more powerful and abstract as we go from lower layers to higher layers.
In a layered scheme, by definition, lower levels cannot use the functionality offered by higher levels. However, the other way around, the situation is more varied. We may choose to allow layer n to use the functionality of each layer m, with m < n. We may also choose to limit the visibility of functionality offered by each layer, and for example restrict layer n to use only the functionality offered by layer n-1. A Design issue in each case is how to assign functionality to the different layers of the architecture, i.e. how to characterize the virtual machine it embodies. If visibility is not restricted, some of the elegance of the layered architecture gets lost. This situation resembles that of programming languages containing low-level bit manipulation operations alongside WHILE statements and procedure calls. If visibility is restricted, we may end up copying functionality to higher levels without increasing the level of abstraction.
Using an example of a layered architectural style for use in telecommunications. It can be seen that layers do not necessarily correspond to different layers of abstraction. Rather, the functionality of the system has been separated. Two main guidelines drive the assignment of functionality to layers in this architecture:
The resulting architecture has four layers:
A similar line of thought can be followed in other domains. For instance, it is hard to predict how future household equipment will be assembled into hardware boxes. Will the PC and the television have the same box? Will the television and the DVD player be combined or will they remain as separate boxes? No one seems to know. Since the half-life of many of these products is about six months, industry is forced to use a building-block approach, emphasizing reuse and the development of product families rather than products. A division of functionality into a hardware-related inner layer, a generic signal processing layer, and a user-oriented service layer suggests itself. The above architecture for telecommunications applications can be understood along the same lines.
In practice, we will usually encounter a mixture of architectural styles. For example, many software environments can be characterized as a combination of the repository and layered architectural styles. The core of the system is a repository in which the various objects, ranging from program texts to work-breakdown structures, reside. Access to these objects as well as basic mechanisms for the execution and communication of tools are contained in a layer on top of this repository. The tools themselves are configured in one or more layers on top of these basic layers. Interaction between tools may yet follow another paradigm, such as implicit invocation.
The software architecture captures early design decisions. Since these early decisions have a large impact, it is important to start testing at this early stage. Testing software architectures is commonly referred to as Software Architecture Assessment. In a software architecture assessment, the software architecture is assessed with respect to quality attributes such as maintainability, flexibility and so on.
It is imporatnt to keep in mind that in this process the architecture is assessed, while one hopes the result will hold for a system yet to be built. As a result, conclusions will often be at quite a general level. Also, there is some uncertainty about whether these results will actually be realized. Suppose the architecture is assessed for maintainability. Even if the outcome is quite positive, a sloppy implementation may yet spoil the rosy picture. Figure 6 illustrates this issue. Architecture assessment takes place at the left-hand side of the figure, while one assumes the results will be valid for the right-hand side.
There are two broad classes of techniques to evaluate a software architecture. The first class comprises measuring techniques, and rely on quantitative information. Examples include architecture metrics and simulation. The second class comprises questioning techniques, in which one investigates hwo the architecture reacts to certain situations. This is often done with the help of scenarios.
There are different types of scenarios one may use in architecture assessments. Common types are:
One of the best known architecture assessment methods is the Architecture Tradeoff Analysis Method. As the name indicates, an important goal of the Architecture Tradeoff Analysis Method (ATAM) is to determine how quality attributes interact. If we decide to include an authorization component to increase security, doing so will likely degrade performance. By making the consequences explicit, it becomes possible for stakeholders to trade off the different possibilities, and make informed decisions, with clear insight into the consequences thereof.
The main steps of the Architecture Tradeoff Analysis Method is listed below. There may be a preparatory phase in which the participants meet to discuss the whole exercise, and a follow-up phase at the end of which a written report is delivered. The early steps are meant to make the participants familiar with the major quality drivers for the system (step 2), the solution chosen (step 3), and the approaches and patterns used in this solution (step 4). In step 5, the quality requirements are articulated in more detail. The project's decision makers are key in this process.
Steps of Architecture Tradeoff Analysis Method
The end result of this exercise is a tree. The root node is termed 'utility'. It expresses the overall quality of the architecture. The next level contains the quality attributes that will be evaluated. These are again broken down into more detailed constituents.
A complete utility tree may contain more scenarios than can be analyzed during the assessment. It is then useful to prioritize scenarios. The Architecture Tradeoff Analysis Method suggests two criteria for doing so. Using the first criterion, the stakeholders indicate how important the scenarios are (i.e. High/Medium/Low). Using the second criterion, the architect ranks the scenarios according to how difficult he believes it will be to satisfy the scenario, using the same 3 point scale. In the remainder of the assessment, one may then concentrate on the scenarios that score High on both scales.
In step 6, the scenarios are discussed one at a time. For each scenario, the architect walks the stakeholders through the architecture, explaining how the architecture supports that scenario. This may trigger a further discussion of the architectural approaches chosen. The end result is a documented list of sensitivity points, tradeoff points, risks and nonrisks, relating the architectural decisions made to the relevant quality attributes.
A Sensitivity Point is a property of the architecture that is critical for a certain quality attribute. For example, the possibility to undo user actions critically affects the usability of our library system, and this property therefore is a sensitivity point with respect to performance. If a decision is a sensitivity point for more than one quality attribute, it is called a Tradeoff Point. If performance is of utmost importance, the decision to include an undo facility may be a risk. if this decision is non-critical, it is a Nonrisk.
The utility tree is based on the main drivers used during the design of the architecture. Its construction is done in consulation with the main decision makers. There are other stakeholders, such as a maintenance manager or security expert, that can also be polled for additional scenarios. This is done is step 7. And, similar to step 5, these scenarios are prioritized, and a selection is made for further study. Similar to step 6, these additional scenarios are analyzed in step 8. Finally, the collected information is summarized and presented to all stakeholders in step 9.
The result of an architecture assessment goes way beyond a list of sensitivity points, tradeoff points, risks and nonrisks. Stakeholders, including the architect, often construct a much deeper understanding of the architecture, its underlying decisions, and the ramifications thereof. Also, a better documentation is often delivered as a byproduct of the assessment. This is similar to the extra benefits software inspections and walkthroughs have besides the identification of software errors.
In practice, organizations often perform software architecture assessments in a less rigid sense than suggested by the above description of the Architecture Tradeoff Analysis Method. Usually, a cafeteria-like approach is followed, whereby those elements from the Architecture Tradeoff Analysis Method and similar methods are chosen that best fit the situation at hand.
Software architecture is concerned with the description of elements from which systems are built, the interaction among those elements, patterns that guide their composition, and constraints on those patterns. The design of a software architecture is driven by quality concerns. The resulting software architecture is described in different views, each of which addresses specific concerns on behalf of specific stakeholders. This resembles the way different drawings of a building emphasize different aspects on behalf of its different stakeholders.
It is important to not only document the resulting solution, but also the decisions that led to that solution, its rationale, and other information that is helpful to guide its further evolution.
Software architecture is an important notion, for more than one reason: