Sebastian's blog

What is software architecture?

tl;dr

A software architecture is a model, resulting from intentional, goal-oriented decisions, about how to solve a problem with software.

The discipline of Software Architecture comprises methods to identify, make, and communicate the necessary decisions and the resulting model.

A Software Architect is someone who applies these methods to a specific problem to reach a concrete set of goals.

Why?

Why yet another definition of software architecture? Don't we have enough definitions already? No, of course not. I am just following standard procedure here. ;-)

On a more serious note, I think each new attempt to define software architecture brings a new perspective to what I see as an evolving field. Maybe some day we will have a common definition of software architecture everyone can agree on similar to other disciplines. But how will we get there if not by iteratively refining our understanding, discussing various aspects, coming up with new descriptions, and trying them on to see how they fit?

It is in this spirit that I present my attempt at a definition, not to replace others, but to add something I have been thinking about a lot, in the hope that someone may find it useful. I am happy to enter into a discussion on Mastodon.

What is software architecture?

I humbly propose the following definition of software architecture. (This definition applies to systems – which may contain non-software parts, such as hardware and people – just as well. I will be using the terms software architecture, systems architecture, and architecture more or less interchangeably.)

A software architecture is a model, resulting from intentional, goal-oriented decisions, about how to solve a problem with software.

This definition consists of several parts, each of which addresses an important aspect.

I will discuss each of them briefly in the following sections, in reverse order.

Building on this definition of a software architecture, the discipline of Software Architecture comprises methods to identify, make, and communicate the necessary decisions and the resulting model, and a Software Architect is someone who applies these methods to a specific problem to reach a concrete set of goals.

A software architecture solves a problem.

Just as the architecture of a building is aimed at a specific purpose – the architect should know if the building is supposed to contain a factory or a sports arena or house a family – the architecture of a piece of software is intended to solve a specific problem. If there is no problem to solve, there is no need for an architecture (and no need for the software).

This is in contrast to architecture styles and architecture patterns, which describe generic approaches or solutions to classes of problems. These are useful because they codify architecture experience and provide guidance to architects, but to become an architecture they have to be applied to a concrete problem.

While solving a problem, there are many different aspects to consider, each of which may have an impact on the final architecture. To be able to address them effectively, they need to be broken down into design goals, which brings us to the next point.

A software architecture is goal-oriented.

Every software system must operate in a certain environment, is subject to a unique set of constraints, and must satisfy its stakeholders' needs, often expressed in the form of functional requirements and quality attribute requirements. The goal of a software system's architecture is to ensure that the implementation will be fit for purpose in the sense that it can operate in the target environment, that it does conform to those constraints, and that it can fulfill the requirements. Thus, environment, constraints, and requirements form a set of design goals that inform the architecture, which in turn means that the resulting architecture is inextricably linked to these design goals. If the goals are chosen differently, the architecture must be designed differently. If the goals change, chances are good that the architecture will also need to change. This is what I mean when I say designing a software architecture is an inherently goal-oriented process.

As a consequence, if you do not have any design goals, you do not have a basis to build an architecture on. Architecture cannot ‘happen’ by chance (also see my notes on intentionality below).

But what if there are no goals?

Sometimes, specific design goals are hard to come by, either because our stakeholders cannot be bothered to put them in concrete terms or because the product we are trying to build is still in an early phase and we only have a vague vision, but few hard requirements. This makes designing an appropriate architecture hard because the whole point of architecture is to meet design goals. In this case, you will have to work with assumptions and formulate goals from them. Only then will you be able to design an architecture that will meet those goals.

What if the goals are wrong?

If you base your design goals on assumptions, you run the risk of being wrong about them. Of course, this risk is always there, but the more assumptions you need to make, the greater the risk becomes.

If the goals are wrong, i.e., they do not represent the actual needs of the stakeholders, you will get an architecture that looks good on paper (because it ostensibly reaches its goals), but will perform badly in practice because it fails to address the real needs.

What if the goals are lost?

While you must have design goals for your architecture work, sometimes these design goals are not written down explicitly and live only in the heads of the architects. The resulting model will still be an architecture, possibly even a good one, but it will be hard to evaluate because no one who was not there during the architecture design can determine how well the architecture meets its unknown goals.

It is also impossible to tell whether there really is an architecture or what you are seeing is just structures that accreted over time.

A software architecture is intentional.

Problems can be solved in many ways, including throwing solutions at them and seeing what sticks, or going from one tiny subproblem to the next and fiddling around until it works. I have seen software systems built this way. I know it can work. I don't think this is architecture, however.

Architecture results from deliberate decisions.

To me, architecture implies a deliberate decision-making and modelling process. There are those who say, every system has an architecture. I disagree. If you have not deliberately formed a model of how to solve a problem, your solution does not have an architecture. It may have a structure (it must have, to be executed by a computer), but it does not have an architecture.

A tree trunk that has been blown over by the wind and fallen over a river may serve as a bridge, but since there is no underlying model, it does not have an architecture.

Photo of a tree trunk lying across a wild river, supported by rocks on either end.
Figure 1: This tree trunk fallen across the river has no architecture.
Image credit: J. M. CC BY-SA 2.0

The same tree trunk, put there deliberately as a solution to river-crossing, does have an architecture, albeit a simple one.

An architecture diagram showing a tree trunk laid across rocks on either side of a river.
Figure 2: This architecture diagram of the above tree trunk shows how it is supposed to span the river.
Architecture lies in the heads of the designers.

You could also say, a system does not ‘have’ an architecture at all. Because the architecture is not a property of the system, but of the system's designers. It is they who form the model of how to solve the problem. Given just the tree trunk mentioned above, there is no simple way to tell whether there exists an underlying architecture. The same is true for software systems, but there it is much worse due to their greater complexity.

Architecture comes before implementation.

If software architecture is intentional (and geared towards reaching certain goals), it must necessarily be done before the software is written. Writing software and then claiming, ‘This is the architecture!’, is like shooting at a blank wall and drawing the target where you hit it instead of first drawing the target and then taking a shot. The result may look similar to someone who has not witnessed the process, but the difference could not be greater.

This also means that an architecture cannot be reliably reverse-engineered. By performing software archaeology, the attempt to discover the underlying structures and design of an existing piece of software, you may indeed discover structures, but without supporting documentation, you will not be able to tell whether these structures were intentionally created to conform to an architecture or whether they have been formed by a different process. Or, in other words, looking at the wall with the hole in it, but no target painted on, how can you tell where the shooter wanted to hit? And how can you even tell whether the shooter took aim at all or wether it was just a random shot?

A software architecture is a model.

As a model, the software architecture is an abstraction, not the software itself. This has a couple of implications.

A model is not the thing itself.

As with the architecture of buildings, a software architecture consists of plans, typically including diagrams that show important components and how they relate to each other. It does not consist of the components themselves. The architecture is separate from the structures (buildings, software) implementing it and typically exists before the structures are built.

This is not an architecture.

Photo of the Spittelhof Estate apartment building in Biel-Benken, Basel, Switzerland. The building has a long, straight front and is surrounded by green grass and woods.
Figure 3: A building itself is not its architecture. It is just a building.
Image credit: Leon CC BY 2.0

This is.

Rough drawing of a government building in Biel, showing its structure with just a few lines.
Figure 4: A (building) architecture is the model of a building.
Image credit: gottm2 CC BY 2.5

If a visitor to this building exclaims, ‘What a great architecture!’, this does not mean that the building itself is the architecture, but that the architecture is immediately apparent to the casual viewer because it has been followed strictly and the builders have refrained from adding elements which would obscure it. However, if they had (like Christo and Jeanne-Claude did when they wrapped the German Reichstag building (website in German)), the architecture would still be there.

A model leaves things out.

As an abstraction, the architecture must necessarily leave many things out. So, what should be part of the model and what should be left out? Since the point of the architecture is to solve a problem, it should only include things relevant to the solution of this problem. This may seem trivial at first glance, but when you consider that the problem statement itself may be unclear, you come to realize that this is not as simple as it sounds.

On the other hand, the model should address all aspects that are important for the solution of the problem. However, since designing and maintaining a software architecture is a deliberate process (as discussed above), it comes at a cost (in terms of effort and time). If we had infinite resources and time, we could make our architecture model so detailed that it would effectively describe an implementation. In practice, we are always working with limited resources and time, so we should constrain our architecture model to those aspects with the largest impact on the shape of the solution and its fit to the problem and goals we are trying to achieve.

Moreover, if we plan to continue developing our solution, we need to consider the impact of ongoing development on the software architecture. If our architecture is too detailed, it will need to be adapted very often as our solution evolves, leading to unnecessarily high costs of change. If our architeture is too coarse, it may not be able to ensure that the solution continues to meet its design goals as changes are made. These two concerns need to be carefully balanced to arrive at a model which contains just enough guard rails to keep development on track with respect to the design goals, but at the same time enables (instead of inhibiting) continuous change.

An undocumeted model is still a model.

A software architecture can exist in the head of a person and still be an architecture. In my view, it does not have to be written down to ‘count’ as an architecture. However, it can be hard to distinguish an architecture that lives only in someone's head from no architecture at all; so, in a team context, documentation is still important.

Decisions shape a model, but they are not the model.

Even though a software architecture is the result of a series of decisions, the decisions alone do not an architecture make. In other words, the architecture does not consist of a series of decisions, but is the model that emerges when all those decisions are applied on top of each other and any conflicts that may arise are resolved.

It is perfectly possible to write down (or read about) any number of decisions and not understand what the result looks like. As long as you do not have this understanding – the model that is the outcome of all these decisions – I argue that you do not have an architecture.

Incidentally, this is why I think keeping only Architecture Decision Records is not enough. You also need an evolving view of the result of those decisions.

How does this relate to other definitions of software architecture?

In this section I want to compare my definition of software architecture to several more or less well-known definitions and examine the differences and similarities.

ANSI/IEEE Std 1471-2000

Software Architecture: 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.

This is a classic definition of software architecture. Many similar definitions refer to components and their relationships, and this one includes a reference to more general ‘principles’.

In my definition, the term ‘model’ subsumes these three elements, and I certainly expect the model to include them all. Instead of further detailing the content of the model, I chose to focus on its intentionality and the purpose of the architecture. This part is completely missing from the ANSI definition. While the word ‘principles’ provides a clue that an architecture must be designed intentionally (since principles, unlike structures, do not simply appear unintentionally), the definition refers to a ‘system’ without saying anything about its purpose. According to this definition, a software architecture does not need to have any goals. However (as I wrote above), to me, if you do not have any goals, architecture becomes meaningless.

Also, I find it important to note that a software architecture is the result of a decision process. If a software architecture is a model arrived at after N decisions, this leaves the possibility open to add another decision, resulting in a different (evolved) architecture, whereas the wording ‘guiding its design and evolution’ in the ANSI definition seems to imply that while the system may evolve (within the frame of its architecture), the architecture itself remains static.

ISO/IEC/IEEE 42010:2011

Architecture: (system) fundamental concepts or properties of a system in its environment embodied in its elements, relationships, and in the principles of its design and evolution.

This one is similar to the ANSI definition, and the changes in the wording do not change my assessment.

Wikipedia

From the article on Software architecture on Wikipedia (accessed on April 19th, 2024):

Software architecture is the set of structures needed to reason about a software system and the discipline of creating such structures and systems. Each structure comprises software elements, relations among them, and properties of both elements and relations.

This definition is completely focused on the structural part of software architecture and ignores intentionality and goal-orientation completely. It allows for purely descriptive (e.g., reverse-engineered) ‘architectures’. To reuse my non-software examples from above, this definition would classify descriptions of both the tree trunk fallen over the river and the hole shot randomly into a wall as architectures if they help you ‘reason about’ the system, irrespective of how they came to be.

To my mind, a set of structures, even if it is helpful, is just a set of structures. To count as an architecture, it needs to be intentionally created to meet a set of design goals.

Ralph Johnson (quoted via Martin Fowler)

In his essay Who Needs an Architect?, Martin Fowler quotes Ralph Johnson like this:

In most successful software projects, the expert developers working on that project have a shared understanding of the system design. This shared understanding is called ‘architecture.’ This understanding includes how the system is divided into components and how the components interact through interfaces. These components are usually composed of smaller components, but the architecture only includes the components and interfaces that are understood by all the developers.

This definition is similar to mine in that it places the architecture in the heads of the designers. If the architecture is the shared understanding of the system design of the developers, it depends more on the people than on the system itself. However, it differs in how it views intentionality. My definition requires the architecture to result from intentional decisions, whereas a shared understanding can be developed after the fact, for example, by a team which has inherited an undocumented system and is building a shared understanding of its structure.

While I agree that this shared understanding is important, in my view it is not sufficient to constitute an architecture. However, it can be transformed into one. If the team discovers a certain structure in the software it has inherited and then intentionally decides to adopt this structure as the basis for further development in order to reach some goal (they are bound to have some goals; why would they bother to deal with this system otherwise?), then it will become part of the architecture.

If the team discovers another structure in the same piece of software and decides to ignore it because it does not help them, it will not become part of the architecture, even though the structure exists (and may continue to exist) and they have developed a shared understanding of it.

Further on in the quote, it says:

architecture is the decisions that you wish you could get right early in a project

Here we have the decisions, which covers the intentionality, and the word ‘right’ implies some sort of goal; if there was no goal, there would be no way to tell if a decision was right. What is missing is that the decisions need to come together in a coherent model to be actually useful.

The quote ends with:

Architecture is about the important stuff. Whatever that is.

While this was probably not meant to constitute a definition of architecture all by itself (it is way too broad for that; is it important to keep your developers fed?) it begs an interesting question: what is important? In my view, this depends on your design goals, which in turn depend on the problem your architecture is supposed to solve. This is why my definition includes both the problem to solve and goal-oriented decisions.

Software Engineering Institute, Carnegie Mellon University

From Software Architecture (accessed on April 19th, 2024):

The software architecture of a system represents the design decisions related to overall system structure and behavior.

This definition seems to imply that a software architecture emerges from a series of decisions, the only requirement being that those decisions relate to the system structure and behavior. While I agree in principle, I think this definition is too lax. As a thought experiment, imagine a series of random ‘design decisions related to overall system structure and behavior’. These decisions will certainly result in something, but would you call it a software architecture? I would not. I think that in order to get to a software architecture, the design decisions need to be oriented towards a common set of goals. Only then will you get a coherent model that can be called an architecture.

Also, the definition seems to equate software architecture with the series of decisions, a kind of event sourcing approach to software architecture. I don't know about you, but I would not be able to actually work with an architecture description consisting only of decision records. I would need to go through them and form a model of the resulting architecture before I could actually do anything with it. So, while it may be possible to reconstruct the architecture given just a series of decision records, this is just the point. The decisions are not the architecture. The resulting model is. In my definition, this distinction is made explicit.

Barry Boehm et al. (1995, via What is your definition of software architecture?)

Barry Boehm and his students at the USC Center for Software Engineering write that:

A software system architecture comprises

I really like that this definition includes the needs of the system's stakeholders and the connection between the system's structural properties and these needs explicitly. In contrast, my definition does not mention the stakeholders explicitly, but it requires the architecture to solve a problem and aligns architectural work (in the form of decisions) to (design) goals.

If the problem an architecture solves is a problem the system's stakeholders actually want to have solved and the design goals align with the stakeholders' needs, I would regard the architecture as good. However, if an architecture solves a problem no one has or its design goals do not align with anyone's needs, I would still regard it as an architecture, albeit a useless one. Strictly speaking, the above definition would not really count the latter example as an architecture because it requires it to address actual stakeholder needs.

On the other hand, even more strictly speaking, it only requires it to address ‘need statements’, which is not the same. The stated needs may not be the real needs, i.e., the statements may be wrong. An architecture based on wrong need statements would still fulfil the definition, so the latter example might actually fulfil the definition after all if the problem (which no one needs solved) and design goals (which do not align with anyone's needs) are written down as stakeholders' need statements, even if they are wrong. Which, for practical purposes, means there is not much of a difference between the USC group's ‘stakeholders' need statements’ and my ‘problem’ and ‘goals’.

This definition also requires there to be a model (not just decisions) and addresses goal-orientation by requiring a rationale that connects the model with the needs/goals. The only part of my definition the USC group's definition does not address at all is the deliberate decision process. As far as this definition is concerned, the architecture could appear out of thin air as long as the rationale can be constructed afterwards.

GitHub

From What is software architecture? (accessed on April 19th, 2024):

Software architecture refers to a set of fundamental structures that developers use as an overarching visual guide when planning for and building out software solutions. These frameworks also ensure that a project meets its technical and business needs by planning for important functionality such as scalability, reusability, and security. These plans are then broken down into individual components and code during the design phase.

This definition includes some elements that do not appear in any of the other definitions.

What about the other elements? The definition limits the scope of software architecture to ‘fundamental structures’, which seems too narrow to me. My idea of the architecture model is more general and includes concepts and principles as mentioned in some other definitions.

The GitHub definition explicitly calls out the use of software architecture for ‘planning and building software solutions’, which aligns with my idea of an intentional and prescriptive (rather than purely descriptive) approach.

It also mentions ‘technical and business needs’, which hints at the problem-solving and goal-orientation aspects, but leaves out the decision-making process.

Conclusion

As the comparison of my definition of software architecture with several other definitions shows, most of them cover one or more of the important aspects of software architecture I discussed in my article, but none of them covers the whole set in quite the same way.

The characterization as a model as opposed to a set of decisions is important because the interplay between the decisions can be non-trivial and you have to know (and understand) the result in order to work with it.

Intentionality is important because an architecture is something you create deliberately.

Designing a software architecture is a goal-orientated process because the whole point of an architecture is to ensure the software meets certain design goals.

An architecture is a means to an end, and the end is to solve a problem. This should always be kept in mind, lest the architecture become an end in itself.

This is why, to me, a software architecture is a model, resulting from intentional, goal-oriented decisions, about how to solve a problem with software.

I hope someone finds these thoughts useful.