P.1. The Role of Architecture

Software architecture has emerged as an important subdiscipline of software engineering, particularly in the realm of large-system development. Architecture, which is the prudent partitioning of a whole into parts, with specific relations among the parts, is what allows groups of peopleoften groups of groups of people separated by organizational, geographical, and even temporal boundariesto work cooperatively and productively together to solve a much larger problem than any of them would be capable of individually. Architecting is "divide and conquer" followed by "now mind your own business" followed by "so how do these things work together?" That is, each part can be built fairly independently of the other parts; in the end, however, these parts must be put together to solve the larger problem. A single system is almost inevitably partitioned simultaneously in a number of different ways: different sets of parts and different relations among the parts.

Architecture is what makes the sets of parts work together as a successful whole. Architecture documentation is what tells developers how to make it so.

For nearly all systems, quality attributes or engineering goalssuch as performance, reliability, security, or modifiabilityare every bit as important as making sure that the software computes the correct answer. Architecture is where these engineering goals are met. Architecture documentation communicates the achievement of those goals.

All these engineering goals and their solutions are purely architectural in nature. Given these uses of architecture, a fundamental question emerges: How do you document an architecture so that others can successfully use it, maintain it, and build a system from it? This book exists to answer that question.

COMING TO TERMS

Software Architecture

If we are to agree on what it means to document a software architecture, we should establish a common basis for what it is we're documenting. Although the term software architecture has multiple definitions, no universal definition exists. The Software Engineering Institute's Web site collects definitions from the literature and from practitioners; so far, more than 90 definitions have been collected. Following are a few of the most-cited definitions from published literature.

By analogy to building architecture, we propose the following model of software architecture: Software Architecture = {Elements, Form, Rationale}. That is, a software architecture is a set of architectural (or, if you will, design) elements that have a particular form. We distinguish three different classes of architectural elements: processing elements; data elements; and connecting elements. The processing elements are those components that supply the transformation on the data elements; the data elements are those that contain the information that is used and transformed; the connecting elements (which at times may be either processing or data elements, or both) are the glue that holds the different pieces of the architecture together. For example, procedure calls, shared data, and messages are different examples of connecting elements that serve to "glue" architectural elements together. (Perry and Wolf, 1992, p. 44)

. . . beyond the algorithms and data structures of the computation; designing and specifying the overall system structure emerges as a new kind of problem. Structural issues include gross organization and global control structure; protocols for communication, synchronization, and data access; assignment of functionality to design elements; physical distribution; composition of design elements; scaling and performance; and selection among design alternatives. (Garlan and Shaw 1993, p. 1)

The structure of the components of a program/system, their interrelationships, and principles and guidelines governing their design and evolution over time. (Garlan and Perry 1995, p. 269)

The software architecture of a program or computing system is the structure or structures of the system, which comprise software components, the externally visible properties of those components, and the relationships among them. By "externally visible properties," we are referring to those assumptions other components can make of a component, such as its provided services, performance characteristics, fault handling, shared resource usage, and so on. (Bass, Clements, and Kazman 1998, p. 27)

An architecture is the set of significant decisions about the organization of a software system, the selection of the structural elements and their interfaces by which the system is composed, together with their behavior as specified in the collaborations among those elements, the composition of these structural and behavioral elements into progressively larger subsystems, and the architectural style that guides this organizationthese elements and their interfaces, their collaborations, and their composition. (Booch, Rumbaugh, and Jacobson 1999, p. 31)

The fundamental organization of a system embodied in its components, their relationships to each other, and to the environment, and the principles guiding its design and evolution. (IEEE 2000a, p. 9)

These and other similar definitions take a largely structural perspective on software architecture. They hold that software architecture is composed of elements, connections among them, and, usually, some other aspect or aspects, such as configuration or style, constraints or semantics, analyses or properties, or rationale, requirements, or stakeholders' needs. Mary Shaw has observed that there seem to be three additional main perspectives on architecture beyond the structural:

  • Framework models are similar to the structural perspective, but their primary emphasis is on the usually singular coherent structure of the whole system as opposed to concentrating on its composition. The framework perspective concentrates on domain-specific software architectures or domain-specific repositories and often elevates middleware or communication infrastructures to a distinguished role.
  • Dynamic models emphasize the behavioral quality of systems. "Dynamic" might refer to changes in the overall system configuration, setting up or disabling preenabled communication or interaction pathways, or the dynamics involved in the progress of the computation, such as changing data values.
  • Process models focus on construction of the architecture and the steps or process involved in that construction. From this perspective, architecture is the result of following a process script.

These perspectives do not preclude one another; nor do they represent a fundamental conflict about what software architecture is. Instead, they represent a spectrum in the software architecture community about the emphasis that should be placed on architecture: its constituent parts, the whole entity, the way it behaves once built, or the building of it. Taken together, they form a consensus view of software architecture and help us make sense of the concept.

PERSPECTIVES

What's the Difference Between Architecture and Design?

The question of how architecture is different from design has nipped at the heels of the architecture community for years.

Fortunately, the answer is easy. Architecture is design, but not all design is architecture. That is, many design decisions are left unbound by the architecture and are happily left to the discretion and good judgment of downstream designers and implementers. The architecture establishes constraints on downstream activities, and those activities must produce artifactsfiner-grained designs and codethat are compliant with the architecture, but architecture does not define an implementation.

You may ask, "What decisions are nonarchitectural? That is, what decisions does the architecture leave unbound and at the discretion of others?" To answer this question, we return to our definition of software architecture, cited in the preface: ". . . the structure or structures of the system, each of which comprises elements, the externally visible properties of those elements, and the relationships among them."

Thus, if a property of an architectural element is not visible, or discernible, to any other architectural element, that element is not architectural. The selection of a data structure, along with the algorithms to manage and access that data structure, is a typical example. Suppose that the architectural prescription for the data structure is that it provides programs, invoked from other architectural elements, that store and retrieve data; whether we choose a linked list, an array, a stack, or any other solution is therefore immaterial to those other elements, as long as our choice lets us meet the developmental, behavioral, and quality requirements levied on us.

"But wait," you protest. "You used the term architectural element: What's that? Are there nonarchitectural elements? If so, what's the difference?"

There may be nonarchitectural elements; their existence is unknown except to those who are outside an architectural context. For instance, a module may correspond to a work assignment for a development team; a module created under the doctrine of information hiding encapsulates a changeable aspect about the system. Modules are hierarchical entities; that is, a complex module, such as a work assignment, can be decomposed into smaller modules: smaller work assignments. Each module has an interface and an implementation. The interface to the parent is a subset of the union of the interfaces of the children.

Suppose that you're in charge of implementing module M and that, as far as the architect has stipulated, M has no submodules. Perhaps you discover that M's interface routines could all be implemented quite straightforwardly if you also designed and implemented a common set of services that they could all use. You assign a small subteam to design and implement thisthisthis what? Well, it's a work assignment, and it encapsulates a changeable secretnamely, the algorithms and data structures used by the common servicesso that makes it a module, a submodule of M. Let's call it M2:

"I get it," you say. "Because its existence is not known outside of M, M2 is not an architectural module."

It's tempting to agree at this point and be done with this, but that's not quite the right way to look at things. In some layered architectures, the layers at the top are not allowed to use the layers at the bottom; in essence, the bottom layers' services are not known to the top layers. But we would never say that the bottom layers of an architecture are nonarchitectural. The argument about "unknown outside of" appeals to a relation different from the one present in a module structure. Modules are related to one another by the contains relation, or shares a secret with relation. Whether a module's services are known or unknown by another module is a property of the uses relation, which is a different kind of animal.

"OK," you say. "So is module M2 an architectural element or not?"

I would say not, but not because it's "invisible" to the other modules outside its parent. I'm afraid you're not going to like the reason. It's a nonarchitectural element because the architect said sothat is, he or she didn't make it part of the architecture.

"You're joking," you say. "That's a completely arbitrary definition!"

Not really. The reason the architect didn't make it part of the architecture is that its existence or nonexistence was not material to the overall goals of the architecture. The architect gave you the freedom to structure your teamimplementing Mas you saw fit.

The fact is, no scale or scope or measure or line divides what is architectural and what is not. One person's architecture may be another person's implementation and vice versa. Suppose that M2 turns out to be very complicated and that the subteam you assign to it begins by giving M2 an internal structure. To the coders of M2, that structure is an architecture. But to the architecture of the system that includes M, the very existence of M2, let alone its internal structure, is an implementation detail.

Modules and other hierarchical elements[1] are subject to confusion about where to draw the line between architecture and nonarchitectural design. If you want to be tediously precise about the matter, the coding of each subroutineor even the coding of a single line of codecould be considered a separate work assignment. Of course, we would not want to consider such minutiae to be architectural: The whole point of architecture is to let us reason about larger issues. So when should an architect stop decomposing modules into smaller and smaller work assignments? One heuristic comes from David Parnas [Parnas, 86, p. 363]. He says that a module is "small enough" when, in the face of a change, it would be just as easy to recode it as it would be to alter it. Technically speaking, you can't know a module's code size at design time, but if you can't make a good guess, you're probably not the right person to be the architect for the system you're working on.

Processes and other nonhierarchical elements can also be nonarchitectural. Suppose that the architect gave you a budget and the freedom to create up to 12 tasks and that these tasks do not synchronize or interact with any other tasks outside your work assignment. In that case, we could make the same argument: that these tasks, or elements, are nonarchitectural.

"All right," you sigh. "Once more, with clarity?"

Sure. Architecture is design, but not all design is architectural. The architect draws the boundary between architectural and nonarchitectural design by making those decisions that need to be bound in order for the system to meet its development, behavioral, and quality goals. (Decreeing what the modules are achieves modifiability, for example.) All other decisions can be left to downstream designers and implementers. Decisions are architectural or not, according to context. If structure is important to achieve your system's goals, that structure is architectural. But designers of elements, or subsystems, that you assign may have to introduce structure of their own to meet their goals, in which case such structures are architectural: to them but not to you.

Architecture is truly in the eye of the beholder. And what does all this have to do with documentation? If your goals are met by an architecture, document it as such, but expect the possibility that subsequent, finer-grained design may produce architectural documentationabout a small piece of your systemon its own.

P.C.C.

[1] By "hierarchical element," we mean any kind of element that can consist of like-kind elements. A module is a hierarchical element because modules consist of submodules, which are themselves modules. A task or a process is not a hierarchical element.

COMING TO TERMS

Documentation, Description, Representation, Specification

What shall we call the activity of writing down a software architecture for the benefit of others or for our own benefit at a later time? Leading contenders are documentation, representation, description, and specification. For the most part, we use documentation throughout this book, and we want to explain our reasoning.

Specification tends to connote an architecture rendered in a formal language. Now, we are all for formal specs. (We have to be. One of usIverscounts himself as a formalist, and he intimidates the rest of us. In an early draft one of us called data flow diagrams a formal notation, and he just about gave himself an aneurysm. We recanted.) But formal specs are not always practical; nor are they always necessary. Sometimes, they aren't even useful: How, for example, do you capture in a formal language the rationale behind your architectural decisions?

Representation connotes a model, an abstraction, a rendition of a thing that is separate or different from the thing itself. Is architecture something more than what someone writes down about it? Arguably yes, but it's certainly pretty intangible, in any case. We felt that raising the issue of a model versus the thing being modeled would only raise needlessly diverting questions best left to those whose hobby, or calling, is philosophy: Does an abstraction of a tree falling in a model of a forest make a representation of a sound? Don't ask me; I haven't a clue. (Better yet, ask Ivers.)

Description has been staked out by the architecture description language (ADL) community. It's mildly curious that the formalists snagged the least rigorous-sounding term of the bunch. (If you don't believe this, the next time you board a jet ask yourself if you hope its flight control software has been specified to the implementers, or merely described.) One would think that the ADL purveyors' ambitions for their languages are not very great, but that is not the case. In any event, we did not want anyone to think that writing down an architecture is tantamount to choosing and using an ADL, so we eschewed description.

That leaves documentation. Documentation connotes the creation of an artifact: namely, a document, which may, of course, be electronic files, Web pages, or paper. Thus, documenting a software architecture becomes a concrete task: producing a software architecture document. Viewing the activity as creating a tangible product has advantages. We can describe good architecture documents and bad ones. We can use completeness criteria to judge how much work is left in producing this artifact and determining when the task is done. Planning or tracking a project's progress around the creation of artifacts, or documents, is an excellent way to manage. Making the architecture information available to its consumers and keeping it up-to-date reduces to a solved problem of configuration control. Documentation can be formal or not, as appropriate, and may contain models or not, as appropriate. Documents may describe, or they may specify. Hence, the term is appropriately general.

Finally, documentation is a longstanding software engineering tradition. Documentation is the task that you are supposed to do because it's good for you. It's what your software engineering teachers taught you to do, your customers contracted you to do, your managers nagged you to do, and what you always found a way not to do. So if documentation brings up too many pangs of professional guilt, use any term you like that's more palatable. The essence of the activity is writing downand keeping currentthe results of architectural decisions so that the stakeholders of the architecturepeople who need to know what it is to do their jobhave the information they need in an accessible, nonambiguous form.

Категории