Fundamentals of Software Architecture

Mark Richards & Neal Ford

O'Reilly Media, Inc.

The software development ecosystem exists in a constant state of dynamic equilibrium: while it exists in a balanced state at any given point in time, it exhibits dynamic behavior over the long term. (…) Architects have an important responsibility to question assumptions and axioms left over from previous eras.

Let’s find out what a software architect is.

  • software architects understand and analyze software systems deeply
  • make trade-offs, often with incomplete information

Everything in software architecture is a trade-off. – First Law of Software Architecture

In the distributed systems book we discovered CAP theorem, and how it’s impossible to have more than two / three traits at the same time… software is defined by time and space, so there are always trade-offs, you can never build a perfect system that solves every problem. Additionally, we have to deal with cost and complexity in the systems, and the more complex the solution is the more difficult it is to maintain. I often like to think that “complexity kills software projects.”

Why is more important than how. – Second Law of Software Architecture

Sure.

Most architecture decisions aren’t binary but rather exist on a spectrum between extremes. – Third Law of Software Architecture

I bet most of the trouble here comes from dealing with stakeholders and business goals.

While the author has trouble defining the difference between an architect and designer, except saying that if it’s difficult to decide then it’s probably the architect’s responsibility. The difference between developers and architects is quite simple. Developers require a significant amount of technical depth while architects require a significant amount of technical breadth, in that they should be familiar with many different technologies, frameworks, languages, etc.

To use a physics analogy, software systems model complex systems, which tend toward entropy (or disorder). In a physical system, energy must be added to preserve order. The same is true for software systems: architects must constantly expend energy to ensure structural soundness, which won’t happen by accident.

Controlling the complexity in software is definitely an important part of the work, but one that stakeholders often don’t understand well.

Software architects need to be aware of architectural characteristics such as:

  • Auditability
  • Performance
  • Security
  • Requirements
  • Data
  • Legality
  • Scalability

Applications can support a huge number of architectural characteristics…but they shouldn’t. Each architectural characteristic that a system supports adds complexity to its design. That’s why architects should strive to choose the fewest possible architectural characteristics rather than the most.

At least we can all agree complexity is important, and yet complexity can’t be reduced:

For any system there is a certain amount of complexity which cannot be reduced. – Tesler’s Law, also known as The Law of Conservation of Complexity

This often happens when you try to simplify a user interface, you can’t remove the complexity but only shift it to the software. If you make the software simpler, you shift the complexity back to the user… so there’s no silver bullet.

Many science-literate architects know of the concept of a quantum from physics, where it refers to the smallest possible amount of something–usually energy. (…) [An] informal definition of architecture quantum is “the smallest part of the system that runs independently.” For example, microservices often form architecture quanta.

When designing systems, it seems best not to focus on the physical implementation of where or how the servers, etc. will be located, but rather focus on the logical components of how the system will fit together. A good way to achieve this is by creating workflows of how the user interacts with the system, or how the systems interact with each other. Workflows might include elements like touchpoints the user interacts with, or notifications, or triggers for payments. Another approach is to use the actors/actions exercise to determine different actors and the actions they need to take in the system, and what their roles and responsibilities are.

A component or service should have limited knowledge of other components or services. – The Law of Demeter

An interesting thought from the author, is that one should also consider how the team organizes their seating in the office: do they work together in small teams in the same room? are different departments separated? Using a layered architecture might make more sense if the business is split into well defined departments. So perhaps something more flexible might also be better if the team is remote or distributed, and also perhaps good to consider how the communication flows between the team.

Organizations which design systems… are constrained to produce designs which are copies of the communication structures of these organizations. – Conway’s Law.

Conway goes further to state it works in the opposite direction, that the design is a result of how the organisation currently communicates, rather than trying to optimize the system and then re-organise the team communication around it. If team communication currently has issues, the bad communication might spread to infect the systems they are building together.

The rest of the book covers different types of architecture styles in more detail:

  • Layered: this is like having a backend with MVC architecture, and a frontend with its own MVC architecture, and they can only talk to each other via an API.
  • Modular Monolith: a monolith using domain-driven design to separate logical components.
  • Pipeline: a functional system made up of different microservices, like using mapReduce across different layers of the architecture… similar to how visual programming looks. (e.g. kafka logs -> filter -> transform -> database)
  • Microkernel: similar to modular monoliths, but the core is smaller and each plugin component can be considered an independent microservice but communication still happens through the core.
  • Service-Based: a monolith with different slices, so each department manages its own logic and user interface, but they share a backend or database… such as billing, and order tracking having their own independent portals.
  • Event-Driven: decoupled microservices that communicate or perform tasks based on events being emitted from a message broker.
  • Space-Based: this is like having a geographically distributed app where each server has its own database, and together they will reach eventual consistency… this allows for infinite scalability but a data layer that syncs over time. It is also very similar to serverless architecture where resources can scale up and down as necessary.
  • Orchestration-Driven Service-Oriented: a legacy approach used by enterprises, which was distributed with high-reusability, designed for high reusability but in reality was difficult to maintain and update.
  • Microservices: an extreme version of domain-driven design, in which each service was also responsible for its own database, etc.

The last section of the book focuses on communication and soft skills, such as using Architectural Decision Records (ADRs), analysing risks, and diagramming.

The book itself seemed quite simple at first glance, but if you’re more familiar with the challenges involved in designing software systems then it provides some nice confirmation or reassurance that others fall into similar traps. It definitely helped crystalize some things I was aware of but didn’t have a name for, but the book might seem like common sense if you’ve already been working on software architecture for a while and experienced these problems first hand. I would say the book is more like a nice way to refresh your memory if you’ve taken a break from software architecture and want to dive back in… but it doesn’t really offer many insights or tips to become a better software architect.

I don’t think it would be as easy to transition into being a software architect, as it requires a large breadth of knowledge that takes a long time to build up… but reading the book would give you a good idea of the kind of things a software architect thinks about on a daily basis.