Featured in Architecture & Design

Monal Daxini presents a blueprint for streaming data architectures and a review of desirable features of a streaming engine. He also talks about streaming application patterns and anti-patterns, and use cases and concrete examples using Apache Flink.

Featured in AI, ML & Data Engineering

Joy Gao talks about how database streaming is essential to WePay's infrastructure and the many functions that database streaming serves. She provides information on how the database streaming infrastructure was created & managed so that others can leverage their work to develop their own database streaming solutions. She goes over challenges faced with streaming peer-to-peer distributed databases.

Five Things Every Developer Should Know about Software Architecture

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.

Related Vendor Content

Related Sponsor

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 c4model.com, 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.

What about information architecture?

Your message is awaiting moderation. Thank you for participating in the discussion.

You are talking about software systems in general without making any attempt to distinguish between different classes of them. It seems that the most important class of software systems, at least in enterprise software, are application software systems ("apps"). Essentially, all apps are based on some form of managing data about a problem domain. The "model" part of their codebase is taking care of that, ideally using a well-designed "information architecture". I can see that your C4 approach takes care of codebase architecture and deployment architecture. But what about information architecture?

Re: What about information architecture?

Your message is awaiting moderation. Thank you for participating in the discussion.

Yes, that's correct. The C4 model is really only focussed on the structural aspects; from the big picture down to the code. Information architecture, domain modelling, business process modelling, user experience, etc are all also important aspects that need to be taken care of (and not mentioned in the article). Techniques like good old-fashioned logical/physical data modelling through to domain-driven design and event storming spring to mind, but information architecture isn't really my area of expertise, so I don't have any specific "best practice" recommendations I'm afraid.

Kudos + nitpick

Your message is awaiting moderation. Thank you for participating in the discussion.

I enjoyed this short article quite a bit. I was around when UML became the next big thing so we all learned it and applied it with fervor. At this point though, I have not seen a UML diagram in many years. I do see value in diagraming however, and in standards for diagramming, and so am curious about C4.

One nitpick: In section 3, you liken the "ivory tower" architect to the first runner in a relay race passing the baton. I do not think this analogy serves your point. The first runner in a relay is an active participant in the activity, running his portion of the track and then finally relinquishing the baton to the next. Perhaps, the "ivory tower" architect is the starter who simply puts the runners in the starting blocks and fires the starting gun?

Re: Kudos + nitpick

Your message is awaiting moderation. Thank you for participating in the discussion.

Thanks, John, you're welcome! Yes, there's a huge amount of value in diagramming, both during up front design and retrospectively, when documenting existing codebases. It's a real shame that more teams don't do this nowadays (or they do it very poorly).

Yes, that first runner should certainly be an active participant. If they're only running the first few metres, and they do that really slowly, they've already set the team up for failure. Also, yes, putting the runners in the starting blocks, and perhaps not telling them which way to run, would also illustrate the point!

Nice article

Your message is awaiting moderation. Thank you for participating in the discussion.

Hi Simon. A very nice article indeed.It clarified my doubts about designing in an Agile based project.In section 3, you mentioned about 'ivory tower' architects. Now, there are many variations in architecture roles itself, like for example Solution Architect, Enterprises Architect, Data Architect etc. I personally feel that Solution Architect is the one who can be closer to the application. And it is difficult for roles like Enterprise Architect to be closer at application level. Your thoughts?Also, given that technology is changing so rapidly, how is a software architect to keep up and be able to design and deliver a software system that can have 'agility' to respond to changes.

The flow when looking at architecture?

Your message is awaiting moderation. Thank you for participating in the discussion.

Good article on the structural aspects of architecture - when designing a new system or adding to an existing one, one should always view it from 10,000 foot above and then drill down to make sense of it. One area that helps to visualize in a design review is the flow in the system. I always wonder how/where one would capture that - I always do it as a separate diagram called a 'flow diagram', i.e. in real usage how does information/data/process flow happen in the system. Many a times just looking at the structural representation of a system may miss some flow aspects that are equally if not more important.