Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage Articles Five Things Every Developer Should Know about Software Architecture

Five Things Every Developer Should Know about Software Architecture

Leia em Português

This item in japanese

Key Takeaways

  • Understanding the basics of software architecture is more important than ever before, given the distributed nature of the software systems we’re now building, and the distributed nature of the teams building them.
  • The sweet spot of up front design, between too much and none at all, should focus on understanding the significant decisions and trade-offs that influence the shape of a software system.
  • Good architects are active members of the development team, from collaborating on code to coaching and providing technical leadership to the team.
  • Communicating about software architecture is challenging. The C4 model can help structure the communication, starting with a context diagram, and working down to more technical aspects of the system.
  • Contrary to some popular assumptions, putting effort towards good architecture actually enables agility.

Back in 2010, I wrote an article titled Are You a Software Architect?, which looked at the difference and transition between being a software developer and being a software architect. Although the industry has moved on in many ways during the past 8 years, it seems that software development teams are still struggling with some of the basics, especially those aspects related to software architecture. These are arguably more important than ever before, given the distributed nature of the software systems we’re now building, and the distributed nature of the teams building them. As a short introduction to the topic and to debunk some myths, here are five things that every software developer should know about software architecture.

1. Software architecture isn’t about big design up front

Software architecture has traditionally been associated with big design up front and waterfall-style delivery, where a team would ensure that every last element of the software design was considered before any code was written. In 2001, the "Manifesto for Agile Software Development" suggested that we should value "responding to change over following a plan," which when taken at face value has been misinterpreted to mean that we shouldn’t plan. The net result, and I’ve seen this first hand, is that some software development teams have flipped from doing big design up front to doing no design up front. Both extremes are foolish, and there’s a sweet spot somewhere that is relatively easy to discover if you’re willing to consider that up front design is not necessarily about creating a perfect end-state. Instead, think about up front design as being about creating a starting point and setting a direction for the team. This often missed step can add a tremendous amount of value to a team by encouraging them to understand what they are going to build and whether it is going to work.

In order to arrive at a software design, you need to make some design decisions. In discussing the difference between architecture and design, Grady Booch tells us that "architecture represents the significant decisions, where significance is measured by cost of change." In other words, which decisions are expensive to change at a later date? Following on from this, a good way to think about up front design is to ensure that you’ve made and understood the trade-offs associated with the "significant decisions." These significant decisions are typically related to technology choices and structure (i.e. decomposition strategies, modularity, functional boundaries, etc.) If you’re building a monolithic software system, the choice of programming language is likely to be significant for a number of reasons. Adopting a microservices architecture potentially reduces the significance of which programming language(s) you choose, but introduces other trade-offs that need thinking through. Similarly, adopting a hexagonal architecture allows you to decouple your business logic from your technology choices, but again there are trade-offs.

The up front design process should therefore be about understanding the significant decisions that influence the shape of a software system rather than, for example, understanding the length of every column in a database. In real terms, I’d like teams to really understand what they are going to build, how they are going to build it (at a high-level, anyway) and whether what they’ve designed will have a good chance of actually working. This can be achieved by identifying the highest priority risks and mitigating them as appropriate, writing code if necessary. In summary, up front design should be about stacking the odds of success in your favour.

2. Every software team needs to consider software architecture

What I've just described applies to every software team; from a 1-person team building a startup in their garage through to a globally distributed team with hundreds of developers. Creating that starting point and direction provides technical leadership. A failure to do this tends to lead to chaos - poorly structured, internally inconsistent codebases (the stereotypical "big ball of mud") that are hard to understand, hard to maintain and potentially don’t satisfy one or more of the important quality attributes such as performance, scalability or security. In short, every team needs technical leadership.

3. The software architecture role is about coding, coaching and collaboration

The image that many people have of software architects is of traditional "ivory tower" software architects dictating instructions to an unsuspecting development team, like the first runner would pass the baton in a relay race. It doesn’t need to be like this though, and many modern software architects instead prefer an approach that favours coding, coaching and collaborative design. Most of the good software architects I've met are also good developers who still enjoy coding, and giving this up isn't necessarily something they want to do anyway. It's also easy for people to lose touch with technology given how quickly it changes. I like to think that software architects should be "master builders," with the implication being that they can and do write code as a part of the team where possible. Being a part of the team, writing code, tends to make the software architecture role much easier too, because you will have a greater understanding of the system being built and other developers will see you as a peer.

It's also worth mentioning that the software architecture role doesn’t necessarily need to be undertaken by a single person. This is often a good place to start, but the role can be a collaborative effort that is shared between a number of people. A word of caution, though. Be wary of advice stating that collaborative technical leadership is easy. It's not, and soft skills are hard. I regularly run software architecture katas where groups of 2-5 people are asked to design a software system, and I've witnessed some of these groups being unable to reach consensus on decisions relating to design and technology choices. In extreme cases, groups have split because of ego and personality conflicts. The key is to understand the team you have, and then make sure you apply the appropriate quantity and style of technical leadership.

4. You don’t need to use UML

Traditional views of software architecture often conjure up images of huge UML (Unified Modeling Language) models that attempt to capture every last drop of detail. Unfortunately, modelling and UML became coupled to the "big design up front" practices of the pre-agile era, and all of this has been thrown away by teams in recent years. In my travels around the world, the percentage of software development teams I meet where nobody on the team even knows UML is increasing.

The common advice from many people these days is to "just use boxes and lines on a whiteboard" as a way to communicate ideas. I have gigabytes of photos of such diagrams from my software architecture katas over the years, and I can say with some degree of confidence that, as an industry, we've lost the ability to communicate software architecture. I've seen every possible diagram you can imagine; from collections of illegible randomly coloured boxes and lines through to diagrams that literally tell you nothing about the solution. Teams that can't communicate software architecture won't be able to create that starting point and direction I described previously.

My solution is an abstraction-first approach to communicating software architecture that I call the "C4 model" - Context, Containers, Components and Code. It's essentially about creating a set of hierarchical, zoomable maps to describe a software system. For any given software system, you create a system context diagram that describes how the system fits into the world around it. You then zoom in to the system boundary to show the containers inside it - a container is a deployable, runnable thing, like a single-page application running in a web browser, a server-side web application, a microservice, a database schema, etc. If useful, you can then zoom further into each container to show the components inside it. Finally, and optionally, you can zoom into each component to show the code level elements (classes, interfaces, functions, objects, etc) it's composed of. The C4 model is notation independent, and although I tend to use a simple "boxes and lines" notation, you can certainly use UML too.

You can find more information, videos, example diagrams and links to tooling at, and it's certainly worth looking at if your team struggles to communicate software architecture and the diagrams on your whiteboards/wiki pages don't make sense.

5. A good software architecture enables agility

There still exists a common misconception that "architecture" and "agile" are competing forces, there being a conflict between them. This simply isn’t the case though. On the contrary, a good software architecture enables agility, helping you embrace and implement change; whether from changes in requirements, business processes, mergers, etc. What is considered a "good architecture" is still up for debate of course but, for me anyway, the core characteristics of a good architecture relate to good modularity reached through an appropriate decomposition strategy. If you've experienced the pain of making a major change to an existing big ball of mud, where seemingly unconnected parts of the codebase break, then you'll appreciate that having a well structured codebase (good modularity) is important.

A big problem I see with teams today is that they adopt, what George Fairbanks calls in his Just Enough Software Architecture book, "architecture indifferent design." In other words, they adopt an architectural style without necessarily considering the trade-offs. In today's world, this is commonly manifested in teams adopting a microservices architectural style simply as a reaction to their existing monolithic codebase being considered a mess. Jokes about these same teams subsequently creating a "distributed big ball of mud" to one side, it turns out that the process of software design and decomposition is hugely important, irrespective of whether you're building a monolithic or a microservices architecture. You don't get agility or a good architecture for free. Some conscious design effort is needed and trade-offs need to be considered. This, again, is why creating that starting point with some up front design is crucially important.

About the Author

Simon Brown is an independent consultant specialising in software architecture, and the author of "Software Architecture for Developers" (a developer-friendly guide to software architecture, technical leadership and the balance with agility). He is also the creator of the C4 software architecture model, which is a simple approach to creating maps of your code. Simon is a regular speaker at international software development conferences and travels the world to help organisations visualise and document their software architecture.

Rate this Article