Sunday, April 20, 2025

Book Review: Principles of Software Architecture Modernization

 One of the more interesting reads in the Software Architecture space right now is Diego Pacheco's and Sam Sgro's 'Principles of Software Architecture Modernization' (published by BPB Publications December 2023).

After introducing some foundational concepts of distributed software architectures, the book dives into a particularly interesting topic: "The Distributed Monolith." This term describes an anti-pattern in architectures attempting micro-services where the functionality is neither isolated nor modular enough to realize the benefits of decomposed micro-services. The idea was popularized by Ben Christensen (author of Hystrix) in his talk, "Don't Build a Distributed Monolith." At its core, the concept highlights a common misconception: distributing a monolithic system will resolve its inherent complexity. In reality, without proper abstractions, boundaries and separation of concerns, complexity not only persists but worsens in a distributed system. Modularity cannot be magically achieved—it requires skill, whether systems are co-located or distributed. This is something I completely agree with. It's both tragic and unfortunate as it is difficult to objectively measure how modular or coupled your system is and is something that just requires a well trained eye.

Sgro and Pacheco identify three key traits of a poorly designed system:

  1. Lack of Isolation: Is there excessive sharing of libraries?

  2. Lack of Independence: Can components evolve independently?

  3. Distributed Complexity: Is there a lack of stable contracts and a clear separation of concerns?

However, the book argues, unless it's a very small company maintaining these principles with an Architect as "design and quality gatekeeper" just doesn't scale. That's certainly on the money. Instead, Pacheco and Sgro suggest that engineers should be "educated with the right principles". This is also on the money. As bringing engineers into the technical vision helps them creates a sense of collaboration and helps them feel more empowered. However, it also relies on engineers being good citizens and shouting for help when it is needed. That part can be easier said than done.

There is a whistle stop tour of many things hot in software right now: AWS Cloud, Sidecars, Container Orchestration, Service Meshes and Chaos engineering. Depending on your background some of it you will know, some of it will be a refresher and some of it will be new.

There are also flying visits to many software tenets that are longer established: Reuse vs. Duplication, Dependency Management, Build vs. Buy, Rewrite vs. Refactor, Backward Compatibility, SOA, Test Pyramid

No good book on Software Architecture is without a tidbit or two on technical debt. The analogy of flavours is used to describe slightly different versions of the same thing which tends to happen in larger code bases without sufficient governance. While the need to do something slightly different (or better) may be valid a better approach is described with another analogy: build another bridge. Imagine a bridge connected two parts of a city. As the population grows, at some point, the bridge won't be big enough anymore. But, don't shut it down. Instead, build one in parallel and gradually move traffic over to the new (the idea sounds very much like parallel contracts, or expand / contract). Key is that a flavour is an unfinished bridge. Instead of the gradual migration, things that are similar just proliferate and become impossible to govern. Yeah, full disclaimer: I've seen that too many times.

One excellent point is regarding embracing new technology: Don't do so without good principles. That seems to be a very common problem. Adopting Spring Boot & Docker led a lot of people to believe that building micro-services is going to be easy - sure doesn't Spring and Docker give you all the principles you need? By the way if you want to have a good laugh on that point, I recommend having a look at David Schmitz hilarious talk: 10 Tips for Failing at microservices

There are several industry anecdotes mentioned which I didn't know and found interesting:
  • StackOverflow is a data center-hosted monolith on 9 servers and serves 2B+ monthly page views. They even removed their Redis caching layer without degradation

  • Uber reported 5 - 10% overhead by running Cassandra on Containers

  • LinkedIn migrated its REST APIs from JSON to Protocol Buffers resulting in a 60% latency reduction and an 8% improvement in resource utilisation

The recurring theme in the book is that things can be more complicated than they appear. Watch out for anti-patterns as much as you watch out for good patterns with many many tips to help you master that complexity and build a great architecture.

Overall, 'Principles of Software Architecture' is probably broader than it is deeper. The breath of topics covered is very impressive and that's why I would recommend this book. Usually Software Architecture books are a little narrower but go deeper into one aspect of Software Architecture. For example, Domain Driven Design is more about abstracting and decomposing, 50 Rules of Scalability focuses heavily on one NFR and Designing Intensive Database Applications is heavily focused on Persistence. Principles of Software Architecture's wider coverage ensures there's something valuable for nearly everyone—whether you're looking to learn something new or simply refresh your knowledge.







Sunday, March 2, 2025

Simon Brown C4

 En route to Dev Nexus in Atlanta , Simon Brown was in Dublin on Thursday evening (2025-02-27) for a very interesting talk about his C4 model for Software Architecture. The first of the evening was an overview of C4 and then after the pizza break, Brown's second talk was about mechanisms to help identify components in existing code bases in order to help you reverse-engineer meaningful component diagrams. The event was hosted by the Dublin Java User's group.

I first came across C4 a few years ago as I felt the various classical approaches to software architecture, such as:

all had a few impractical things in common. More specifically, they take too long to deliver real value and can just feel dated. This is likely because they evolved in a pre-agile, pre-CI/CD and pre-micro-service world.

So, Google took me to C4. After watching a few YouTube videos and reading some well-structured documentation, I was comfortable to get started. I really liked how easy C4 was to pick up.

Pairing some domain knowledge and systems knowledge about the external systems we were interacting with, I had enough to put together a useful C4 Context diagram. A C4 Context reminded me of a System Context viewpoint. Although as Brown went further into his presentation I noticed he tends to use the term: "System Landscape" to describe that very big picture others may call "System Context".

Anyway, what I really liked about the Context view was the emphasis it put on describing the people who use your system. Give them an icon, a role / persona and a terse description. In no time you have all the various types of people interacting with your system on one page. Similarly, depicting your software system as a blue-colored box and everything it interacted with as their own grey boxes provided a useful big-picture view of the wider ecosystem— and a reminder software rarely exists on its on.

The Containers view (similar to a deployment view in other Arch modelling styles) is next. Again you can put these together fairly quickly. The Containers view isn't something to be confused with Docker. Brown does make the point he came up with the use of the word "container" first but of course his usage of the word isn't the Docker one. To me, what he means is the "containers" is like something that can just be independently deployed. This covers you for various micro-services you may have and those other services that deviate a little from mirco-services principles but are still deployed separately (probably a bit more like SOA).

Some key C4 principles at play here included:
  • Give the diagram a name

  • Give every box a terse description

  • Say what the technology it is: Spring Boot, J2EE app.

In this view we can also throw in a few AWS services (or whatever you need) and you quickly also have something else very useful on one page.

Note: for both of the Context and Container diagrams, I used draw.io, which conveniently includes built-in C4 icons (as well as an extensive AWS palette and and many other useful bits and bobs)

C4 has two further levels of abstraction:
  • Components

  • Code

Components, are the view lower than containers and higher than code - but you can define the level as you see fit. For me, I try to line this up with either higher level java packagers or jar files. But you need to ensure these things themselves are using some modular principles otherwise the components are not going to be pretty.

The Code view in C4 is really just class and package diagrams. You can use UML here if you want to.

What I really like about C4 is that you move from a high level of abstraction that helps align with Product Managers / Product Owners (so business emphasis and little technical jargon) to something that helps you align with development teams quickly. This mind set of zooming in and zooming out is a key part of software architecture. Get too stuck in the weeds you miss the big picture, but avoid the weeds completely and they just end up growing all the way up to your ivory tower until another form of havoc gets you!

So C4, is definitely something helpful. Not surprisingly about half the attendees on the evening said they were also using it in their own respective roles and companies (most using draw.io or mermaid).

There was some interesting discussion points why some people really dislike UML. Simon went through the proverbial reasons why people don't like it and made one really good point I never thought about before: for some reason it creates this sense for the need of perfection. You can't just draw a line, you have to know if it's a clear diamond or a black diamond? And isn't that just so annoying? The inclination for perfection starts slowing everyone down and creates a sense of "sign - off" - and thus increases inertia to any change.

Simon made the salient point he does in many of his presentations: "moving fast as a team requires great communication". Simple but true. How can any sort of team (not just software) move fast if communication is a challenge?

The C4 attempts to hit the sweet spot. Make communicating with the various stakeholders (business stakeholders to development teams) easier so you can all move faster.

All good stuff.

The second half of the evening was Simon's second presentation. He went through some techniques he was using to reverse engineer a component architecture out of an existing code base. Roughly speaking, it was based on looking for primary and secondary style responsibilities, identifying naming conventions and then using some DSL style stuff to get some neat looking diagrams.

He made a prescient point that you can only really do this if the code base is at a minimum level of health. Too much technical debt and you are wasting your time. GIGO holds true.

Hard to disagree with that.

One last point, he did emphasise the importance of package name spacing and governance in terms of component governance and really think this point is crucial. If you can't control the packaging, you are probably not controlling any sort of components beneath the level of deployables. And if don't have components of any sort - do you really have any sort of architecture useful for developers and construction?

He used the term "model - code gap" (coined by George Fairbanks) a few times to describe the phenomenon of software architects thinking there's an architectural model but the code doesn't line up to this in any way at all. It's a useful term to politely describe the pitfalls of ivory tower architecture - drawing nice pictures when the reality is the code base is closer to a ball of mud.

Overall, a highly relevant and practical talk.