There is a tendency in the world of software development to throw jargon around to create a buzz, sometimes accompanied with the hope that busyness will be a passable stand-in for substance. As a concept, software architecture has sometimes suffered this fate, with marketeers and consultants playing vagueness off against grand gestures and more buzz words.
The good news is that in amidst the marketecture and hand-waving, there are a number of clear points of view that shed light on the notion of software architecture. In trying to define software architecture we are going to make a choice about which ideas to emphasise – ironic since, as we will see, architecture is all about the choices we make.
The idea of choice makes settling on a definition of software architecture appear somewhat arbitrary, but it is anything but: in using a word to characterise something that we do or produce, there is little benefit in using words to reflect something that we do not believe in or do not value. And even before worrying about utility, there is the more fundamental question of agreement: it matters more that two people on a project have a common understanding of what is implied by software architecture than that one of them has a better definition than the other.
From building structure to software structureGiven that the word architecture is taken from the world of buildings and construction, that source may offer some useful inspiration. In the built environment architecture refers both to the art and practice of designing and constructing buildings and to their style and structure. Taking this definition wholesale into the world of software suggests that architecture is concerned with structure. This sounds good until we ask a simple question: what does structure mean for software?
Unlike buildings, software is not physical and so the concept of structure does not have a single obvious and dominant interpretation. Instead of a unique and privileged viewpoint, many perspectives are possible: classes and their relationships; packages and their dependencies; deployable components and the runtime arrangement of a system; source files; indentation of code; layer and tiers; the appearance of the user interface; the APIs between systems and subsystems; and so on. These are all valid interpretations of structure. In their seminal book, Software Architecture: Perspectives on an Emerging Discipline, Mary Shaw and David Garlan summarise what these various interpretations have in common:
The architecture of a software system defines that system in terms of computational components and interactions among those components.Note that the use of the word component is more general than its specific usage in the world of component-based development: it simply refers to an element of a system, whether a development-time class, a runtime object or a deployment-time DLL. Another thing to note is that there is an emphasis on interconnections and the dynamics of what goes on between components: you can’t reasonably talk about components unless you also talk about how they interconnect and interconnect. This view is reinforced by many other publications, including Software Architecture in Practice by Len Bass, Paul Clements and Rick Kazman:
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.But is structure all there is to software architecture? Most developers assume that architecture also has some relationship to the requirements, reasoning and trade-offs involved in developing a system. Shaw and Garlan make this assumption explicit:
In addition to specifying the structure and topology of the system, the architecture shows the correspondence between the system requirements and elements of the constructed system, thereby providing some rationale for the design decisions.In other words, a useful definition of software architecture embraces the what, how and why of structure. In Architecting Enterprise Solutions: Patterns for High-Capability Internet-Based Systems, Paul Dyson and Andy Longshaw take a similar structural view as the starting point for trying to capture and characterise a system’s architecture:
Our position is that an architectural definition is something that answers three questions:How a system’s architecture is described, therefore, depends on the nature of the system, its developers and the surrounding organisation. A small, collocated team of skilled developers working on a system based on familiar concepts typically requires less ceremony and formality than a large team, or a development distributed across multiple sites, or a team with a high proportion of novice developers, or a system based on unfamiliar concepts.
This ‘something’ could be a sketch on the back of a napkin, drawn as part of a lunchtime conversation; reams of technical diagrams and related descriptions; or a short description of the patterns along with a couple of block diagrams.
- What are the structural elements of the system?
- How are they related to each other?
- What are the underlying principles and rationale that guide the answers to the previous two questions?
Architecture defines a model of communication between developers and a place that they, in a virtual sense, inhabit. A description that doesn’t communicate effectively is of little use and can be an unpleasant place to work. An architectural description that is complicated or convoluted hints at one – or both – of two things: the architecture itself is unnecessarily complex, so the complexity is in the architecture rather than description; the description of the architecture is poor, so the complexity arises from the description rather than the architecture. Specifically why an architecture is overly complex or why a description is poor is a separate question, for which there may be many possible answers, such as overly clever or speculative design, bureaucratic company culture, loss of control over legacy parts of a code base, and so on.
Significant design decisionsSo far, the discussion of architecture has focused on structure and rationale, and to good effect, but there is another valuable perspective on software architecture that is equally valid. As Martin Fowler notes, in Patterns of Enterprise Application Architecture:
“Architecture” is a term that lots of people try to define, with little agreement. There are two common elements: One is the highest-level breakdown of a system into its parts; the other, decisions that are hard to change.This second aspect – design decisions that are hard to change – forms the basis of one of the simplest and most direct definitions of architecture, as blogged by Grady Booch:
All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change.This makes clear that design and architecture are not divorced from one another: architecture represents strategic design as opposed to tactical design. Design is made up of many decisions: decisions made consciously or unconsciously; decisions made intentionally or accidentally; decisions imposed externally or taken locally; decisions taken by a team in a meeting or by a programmer in code.
Importantly, not all decisions are necessarily just structural, as defined by components and relationships; some may relate to policy, such as naming conventions or use of exceptions.
What distinguishes architecture from other design is significance as expressed by difficulty or cost of change. Many costly decisions will concern the consequences of changing structure, but others may relate to matters of policy that are not as obviously structural. Consider, for example, the difficulty associated with renaming API classes that have already been published to other parties. Or, in a system without automated unit tests where developers have used exceptions in ad hoc manner, the cost of introducing a more coherent and consistent exception usage policy. In these cases, the cost of apparently trivial decisions has been amplified by the context and nature of a system – these decisions have become architectural in nature.
The good, the bad and the unsustainableIt appears that we now have a reasonably workable definition of software architecture as a practice and a perspective that brings together the notions of design, structure, style, rationale, process and cost. One remaining issue that has been touched on but not explored is the question of evaluating the quality of a system’s architecture.
In defining software architecture many authors, architects and industry analysts attempt to equate architecture with good architecture. This is invariably a category mistake. To say that something is good is to make a judgement concerning its quality. The issue is not whether or not a system has architecture, but whether its architecture is good or not. All systems have architecture, whether intentional or accidental, explicit or implicit, good or bad – even “no architecture” systems have architecture!
Having related architecture to cost of change, we have a simple way of evaluating architectural quality. It is not that a good architecture makes a system cheap to create; it is that it is also cheap to evolve. In other words, a good architecture is one in which the significance of design decisions is minimised. You are free to change many aspects of a system without the fear that such changes are challenging, costly or create a cascade of bugs. A good architecture is therefore a sustainable one.
How does this view of architectural quality relate to structure? It encourages components – classes, packages, assemblies, etc. – that are strongly cohesive and loosely coupled. In a tightly coupled system the cost of change is invariably higher, and what should be minor design decisions become architectural in scope and cost.
In a loosely coupled architecture, where assumptions are well encapsulated, the effect of change is better isolated and the cost of change is typically lower, so that minor design decisions stay minor and many that might initially have appeared to be major are also downgraded in significance.
Kevlin Henney is an independent consultant and trainer based in the UK. He specialises in programming languages, OO design, patterns, development process and software architecture, and is co-author of two recent volumes in the Pattern-Oriented Software Architecture series. He is a regular speaker at DevWeek, and will present the keynote at Software Architect 2007 at the Barbican Conference Centre on 13th June.