1. Introduction

In this chapter we provide an introduction to the topic of software architecture. We briefly discuss what architecture is and why it is fundamental to take it into account when developing software systems. We also discuss the different activities that are associated with the development of software architecture so that architectural design—which is the primary topic of this book—can be understood in the context of these activities. We also briefly discuss the role of the architect, who is the person responsible for creating the design. Finally, we introduce the Attribute-Driven Design (ADD) method, the architecture design method that we will discuss extensively in this book.

1.1 Motivations

Our goal in this book is to teach you how to design software architecture in a systematic, predictable, repeatable, and cost-effective way. If you are reading this book, then presumably you already have an interest in architecture and aspire to be an architect. The good news is that this goal is within your grasp. To convince you of that point, we will spend a few moments talking about the idea of design—the design of anything—and we will see how and why architectural design is not so different. In most fields, “design” involves the same sorts of challenges and considerations—meeting stakeholder needs, adhering to budgets and schedules, dealing with constraints, and so forth. While the primitives and tools of design may vary from field to field, the goals and steps of design do not.

This is encouraging news, because it means that design is not the sole province of wizards. That is, design can be taught, and it can be learned. Most design, particularly in engineering, consists of putting known design primitives together in (sometimes innovative) ways that achieve predictable outcomes. Of course, the devil is in the details, but that is why we have methods. It may seem difficult at first to imagine that a creative endeavor such as design can be captured in a step-by-step method; this, however, is not only possible but also valuable, as Parnas and Clements have discussed in their paper “A Rational Design Process: How and Why to Fake It”. Of course, not everyone can be a great designer, just as not everyone can be a Thomas Edison or a LeBron James or a Ronaldo. What we do claim is that everyone can be a much better designer, and that structured methods supported by reusable chunks of design knowledge, which we provide in this book, can help pave the road from mediocrity to excellence.

Why are we writing a book on software architecture design? While much has been written about design in general, and while there have been some writings on software architecture design, there is no existing book dedicated solely to architecture design. Moreover, most of what has been written on architecture design is relatively abstract.

Our goal in writing this book was to provide a practical method that can be enacted by any competent software engineer, and also (and just as important) to provide a set of rich case studies that realize the method. Albert Einstein was reputed to have said, “Example isn’t another way to teach, it is the only way to teach”. We firmly believe that. Most of us learn better from examples than from sets of rules or steps or principles. Of course, we need the steps and rules and principles to structure what we do and to create the examples, but the examples speak to our day-to-day concerns and help us by making the steps concrete.

This is not to say that architecture design will ever be simple. If you are building a complex system, then chances are that you are trying to balance many competing forces—things like time to market, cost, performance, evolvability, usability, availability, and so on. If you are pushing the boundaries in any of these dimensions, then your job as an architect will be even more complex. This is true in any engineering discipline, not just software. If you examine the history of building large ships or skyscrapers or any other complex “system”, you will see how the architects of those systems struggled with making the appropriate decisions and tradeoffs. No, architecture design may never be easy, but our purpose is to make it tractable and achievable by well-trained, well-educated software engineers.

1.2 Software Architecture

Much has been written on what software architecture is. We adopt the definition of software architecture from Software Architecture in Practice (third edition):

The software architecture of a system is the set of structures needed to reason about the system, which comprise software elements, relations among them, and properties of both.

As you will see, our design method embodies this definition and helps to guide the designer in creating an architecture that has the desired properties.

1.2.1 The Importance of Software Architecture

Much has also been written on why architecture is important. Again, following Software Architecture in Practice, we note that architecture is important for a wide variety of reasons, and a similarly wide variety of consequences stem from those reasons:

Image An architecture will inhibit or enable a system’s driving quality attributes.

Image The decisions made in an architecture allow you to reason about and manage change as the system evolves.

Image The analysis of an architecture enables early prediction of a system’s qualities.

Image A documented architecture enhances communication among stakeholders.

Image The architecture is a carrier of the earliest and hence most fundamental, hardest-to-change design decisions.

Image An architecture defines a set of constraints on subsequent implementation.

Image The architecture influences the structure of an organization, and vice versa.

Image An architecture can provide the basis for evolutionary, or even throwaway, prototyping.

Image An architecture is the key artifact that allows the architect and the project manager to reason about cost and schedule.

Image An architecture can be created as a transferable, reusable model that forms the heart of a product line.

Image Architecture-based development focuses attention on the assembly of components, rather than simply on their creation.

Image By restricting design alternatives, architecture channels the creativity of developers, reducing design and system complexity.

Image An architecture can be the foundation for training a new team member.

If an architecture is important for all of these reasons—if it affects the structure of the organization, and the qualities of the system, and the people involved in its creation and evolution—then surely great care must be taken in designing this crucial artifact. Sadly, that is most often not the case. Architectures often “evolve” or “emerge”. While we have nothing against evolution or emergence, and while we emphatically are not arguing for “big design up front”, doing no architecture at all is often too risky for anything but the simplest projects. Would you want to drive over a bridge or ride in a jet that had not been carefully designed? Of course not. But you use software every day that is buggy, costly, insecure, unreliable, fault prone, and slow—and many of these undesirable characteristics can be avoided!

The core message of this book is that architecture design does not need to be difficult or scary; it is not the sole province of wizards; and it does not have to be costly and all done up front. Our job is to show you how and convince you that it is within your reach.

1.2.2 Life-Cycle Activities

Software architecture design is one of the software architecture life-cycle activities (Figure 1.1). As in any software project life cycle, this activity is concerned with the translation of requirements into a design into an implementation. Specifically, the architect needs to worry about the following issues:

Image Architectural requirements. Among all the requirements, a few will have a particular importance with respect to the software architecture. These architecturally significant requirements (ASRs) include not only the most important functionality of the system and the constraints that need to be taken into account, but also—and most importantly—quality attributes such as high performance, high availability, ease of evolution, and iron-clad security. These requirements, along with a clear design purpose and other architectural concerns that may never be written down or may be invisible to external stakeholders, will guide you to choose one set of architectural structures and components over another. We will refer to these ASRs and concerns as drivers, as they can be said to drive the design.

Image Architectural design. Design is a translation, from the world of needs (requirements) to the world of solutions, in terms of structures composed of code, frameworks, and components. A good design is one that satisfies the drivers. Architectural design is the focus of this book.

Image

FIGURE 1.1 Software architecture life-cycle activities

Image Architectural documentation. Some level of preliminary documentation (or sketches) of the structures should be created as part of architectural design. This activity, however, refers to the creation of a more formal document from these sketches. If the project is small and has a precedent, then architecture documentation may be minimal. In contrast, if the project is large, if distributed teams are collaborating, or if significant technical challenges exist, then architectural documentation will repay the effort invested in this activity. While documentation is often avoided and derided by programmers, it is a standard, non-negotiable deliverable in almost every other engineering discipline. If your system is big enough and if it is mission critical, it should be documented. In other engineering disciplines, a “blueprint”—some sort of documented design—is an absolutely essential step in moving toward implementation and the commitment of resources.

Image Architectural evaluation. As with documentation, if your project is nontrivial, then you owe it to yourself and to your stakeholders to evaluate it—that is, to ensure that the decisions made are appropriate to address the critical requirements. Would you deliver code without testing it? Of course not. Similarly, why would you commit enormous resources to fleshing out an architecture if you had not first “tested” the design? You might want to do this when first creating the system or when putting it through a major refactoring. Typically evaluation is done informally and internally, but for truly important projects it is advisable to have a formal evaluation done by an external team.

Image Architectural implementation/conformance checking. Finally, you need to implement the architecture that you have created (and evaluated). As an architect, you may need to tweak the design as the system grows and as requirements evolve. This is normal. In addition to this tweaking, your major responsibility during implementation is to ensure conformance of the code to the design. If developers are not faithfully implementing the architecture, they may be undermining the qualities that you have designed in. Again, consider what is done in other fields of engineering. When a concrete foundation for a new building is poured, the building that rests on top of that foundation is not constructed until the foundation has first been tested, typically via a core sample, to ensure that it is strong enough, dense enough, sufficiently impermeable to water and gases, and so forth. Without conformance checking, we have no way of ensuring the quality of what is being subsequently constructed.

Note that we are not proposing a specific life-cycle methodology in Figure 1.1. The stereotype <<precedes>> simply means that some effort in an activity must be performed, and hence precede, effort in a later activity. For example, you cannot perform design activities if you have no idea about the requirements, and you cannot evaluate an architecture if you have not first made some design decisions.

Today most commercial software is developed using some form of Agile methodology. None of these architecture activities is incompatible with Agile practices. The question for a software architect is not “Should I do Agile or architecture?”, but rather “How much architecture should I do up front versus how much should I defer until the project’s requirements have solidified somewhat?” and “How much of the architecture should I formally document, and when?” Agile and architecture are happy companions for many software projects.

We will discuss the relationship between architecture design and various software life-cycle methods and process models, including iterative development, in Chapter 9.

1.3 The Role of the Architect

An architect is much more than “just” a designer. This role, which may be played by one or more individuals, has a long list of duties, skills, and knowledge that must be satisfied if it is to be successful. These prerequisites include the following:

Image Leadership: mentoring, team-building, establishing a vision, coaching

Image Communication: both technical and nontechnical, encouraging collaboration

Image Negotiation: dealing with internal and external stakeholders and their conflicting needs and expectations

Image Technical skills: life-cycle skills, expertise with technologies, continuous learning, coding

Image Project skills: budgeting, personnel, schedule management, risk management

Image Analytical skills: architectural analysis, general analysis mindset for project management and measurement (see the sidebar “The Meaning of Analysis”)

A successful design is not a static document that is “thrown over the wall”. That is, architects must not only design well, but must also be intimately involved in every aspect of the project, from conception and business justification to design and creation, through to operation, maintenance, and eventually retirement.

1.4 A Brief History of ADD

While an architect has many duties and responsibilities, in this book we focus on what is arguably the single most important skill that a software engineer must master to be called “architect”: the process of design. To make architectural design more tractable and repeatable, in this book we focus most of our attention on the Attribute-Driven Design (ADD) method, which provides step-by-step guidance on how to iteratively perform the design activity shown in Figure 1.1. Chapter 3 describes the most recent version of ADD, version 3.0, in detail, so here we provide a bit of background for those who are familiar with previous versions of ADD. The first version of ADD (ADD 1.0, originally called ABD, for “Architecture-Based Design”) was published in January 2000, and the second version (ADD 2.0) was published in November 2006. The third edition of the book Software Architecture in Practice presents this method with a reduced number of steps. This discussion, however, does not introduce a new version of ADD, but rather a repackaged version that summarizes the actual steps of the method.

ADD is, to our knowledge, the most comprehensive and most widely used documented architecture design method. (We provide an overview of a number of alternative design methods in Chapter 7.) When ADD appeared, it was the first design method to focus specifically on quality attributes and their achievement through the creation of architectural structures and their representation through views. Another important contribution of ADD is that it includes architecture analysis and documentation as an integral part of the design process. In ADD, design activities include refining the sketches created during early design iterations to produce a more detailed architecture, and continuously evaluating the design.

While ADD 2.0 was useful for linking quality attributes to design choices, it had several shortcomings that needed to be addressed:

Image ADD 2.0 guides the architect to use and combine tactics and patterns to achieve the satisfaction of quality attribute scenarios. Patterns and tactics are abstractions, however, and the method did not explain how to map these abstractions to concrete implementation technologies.

Image ADD 2.0 was invented before Agile methods became widely adopted and, therefore, did not offer guidance for architecture design in an Agile setting.

Image ADD 2.0 provided no guidance on how to begin the design process. While this omission enhanced its generalizability, it presented difficulties for novice designers, who often do not know where to begin. Specifically, ADD 2.0 did not explicitly promote the (re)use of reference architectures, which are an ideal starting point for many architects, as we will discuss later in this book.

Image ADD 2.0 did not explicitly consider different design purposes. For example, one might be doing design as part of a pre-sales process or as part of “standard” design for construction. These are very different purposes and will result in different uses of ADD.

Image ADD 2.0 did not consider that design requires some architectural concerns (i.e., internal requirements) to be addressed whether or not they are expressed in the list of “traditional” drivers (requirements and constraints). It is a rare user who will ask that a system be “testable” or will require that the system provide special testing interfaces, but a wise architect might choose to include such an infrastructure, particularly if the system is complex and used in contexts that are difficult to control and replicate.

Image ADD 2.0 iterations are always driven by the selection and decomposition of architectural elements. This occurs because ADD 2.0 instructs that first an element to decompose must be chosen, and then the drivers must be identified. In ADD 3.0, we recognize that sometimes a design step is driven by the critical architectural requirements, which guides the selection and decomposition of elements.

Image ADD 2.0 includes (initial) documentation and analysis, but they are not explicit steps of the design process.

ADD 3.0 addresses all of these shortcomings. To be sure, ADD 3.0 is evolutionary, not revolutionary. It was catalyzed by the creation of ADD 2.5,1 which was itself a reaction to attempting to use ADD in the real world, in many different contexts.

1. This is our own coding notation; the 2.5 number is not used elsewhere.

We published ADD 2.5 in 2013. In that work, we advocated the use of application frameworks such as JSF, Spring, or Hibernate as first-class design concepts. This change was intended to address ADD 2.0’s shortcoming of being too abstract to apply easily. ADD starts with drivers, systematically links them to design decisions, and then links those decisions to the available implementation options, including externally developed components. For Agile development, ADD 3.0 promotes quick design iterations in which a small number of design decisions are made, potentially followed by an implementation spike. In addition, ADD 3.0 explicitly promotes the (re)use of reference architectures and is paired with a “design concepts catalog”, which includes a broad selection of tactics, patterns, frameworks, reference architectures, and technologies (see Appendix A).

1.5 Summary

Having covered our motivations and background, we now move on to the heart and soul of this book. In the next few chapters, we describe what we mean by design and by architectural design in particular, we discuss ADD, and we provide three case studies showing in detail how ADD can be used in the real world. We also discuss the critical role that analysis plays in the design process and provide examples of how analysis can be performed on design artifacts.

1.6 Further Reading

Fred Brooks has written a thoughtful series of essays on the nature of design, reflecting his 50 years of experience as a designer and researcher: F. P. Brooks, Jr. The Design of Design: Essays from a Computer Scientist. Addison-Wesley, 2010.

The usefulness of having a documented process for design and other development activities is discussed in D. Parnas and P. Clements, “A Rational Design Process: How and Why to Fake It”, IEEE Transactions on Software Engineering, SE-12, 2, February 1986.

The definition of software architecture used here, as well as the arguments for the importance of architecture and the role of the architect, all derive from L. Bass, P. Clements, and R. Kazman, Software Architecture in Practice, 3rd ed., Addison-Wesley, 2012.

Several books cover the different activities of the architecture development life cycle, including G. Fairbanks, Just Enough Software Architecture: A Risk Driven Approach, Marshall & Brainerd, 2010, and the ones whose design approaches are described in Chapter 7.

An early reference for the first version of ADD can be found in F. Bachmann, L. Bass, G. Chastek, P. Donohoe, and F. Peruzzi, The Architecture Based Design Method, CMU/SEI-2000-TR-001. The second version of ADD was described in R. Wojcik, F. Bachmann, L. Bass, P. Clements, P. Merson, R. Nord, and W. Wood, Attribute-Driven Design (ADD), Version 2.0, CMU/SEI-2006-TR-023. The version of ADD that we have referred to here as ADD 2.5 was published in H. Cervantes, P. Velasco-Elizondo, and R. Kazman, “A Principled Way of Using Frameworks in Architectural Design”, IEEE Software, 46–53, March/April 2013.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset