Logo

dev-resources.site

for different kinds of informations.

The Architecture Might Not Be the Problem

Published at
3/14/2024
Categories
architecture
patterns
Author
alexmacarthur
Categories
2 categories in total
architecture
open
patterns
open
Author
13 person written this
alexmacarthur
open
The Architecture Might Not Be the Problem

It’s interesting how language around service architecture changes as patterns fall in & out of favor.

People who advocated for microservices years ago now refer to them as “nano” services. It seems to get at the costly hassle it can be to integrate with, iterate on, and maintain a service with such a narrow purpose. Something “nano” is annoyingly small, whereas something “micro” is just the product of good design.

On the other hand, “monolith” was becoming an engineering slur. It was less than a pattern; more of a digital junk drawer. You only used the word if you were disparaging a system written by engineers who came before you.

But now, you hear more talk of “modular” monoliths — a more palatable way to describe a similar architectural ethos, but in a way that distances yourself from the poor implementations of the past.

At the same time, the monolithic legend Ruby on Rails is seeing a resurgence as teams are reeling with the tradeoffs of more tumultuous architectures, and Laravel continues to explode, even catching notable attention from other communities (despite PHP being dead — incredible).

Regardless of what architectural trends look like at a given moment, the language around them attempts to get at the same thing: how well-suited an architecture is to meet a need.

But being how consistently inconsistent they are, I wonder if the underlying patterns we use are as critical to an effective system as much as we seem to think.

An Imagined Scenario

I’m not old or wise enough to definitively know why these shifts occur like clockwork every few years, but it's fun to speculate anyway. Let’s imagine:

You’re on a team that owns a monolithic service. It’s relatively new, but given a little time, the system starts to show its cracks. They’re not a problem at first; easy enough to walk over without really noticing. Maybe it’s the occasional bug dismissed as an edge case. Or perhaps a small change that took too long to ship, but that was shrugged off because you have new engineers who are just unfamiliar with the codebase. Nothing's on fire and there's no negative impact to business or productivity. Stuff like this just happens (and really, it does).

But eventually, those cracks swell. It's harder to walk, and your team finds itself outright tripping more frequently. The stumbles are mostly just annoying, but quickly enough, crippling. The pipeline is consistently blocked, and you’re playing Whack-a-Bug every time you do get around to shipping something (which seems to rarely happen nowadays anyway).

It’s clear that you can no longer afford to work with the status quo. So, you take inventory of the pain. Some of it can be eased with operational tweaks, but a long-term fix needs to go deeper. You want to get at the root of the problem. Uprooting the tree altogether certainly does that (sorry for switching metaphors here).

But you’re not naïve. You know that the old system was, at one point, built from scratch too. So, you’ll do it differently. And conveniently, the biggest pain points can be neatly grouped under a single heading: the architecture.

  • The pipeline's always clogged because teams are competing for stage time in a single monolithic application!
  • Bugs keep popping up because there's so much intertwined code shoved into a monolithic application!
  • It takes so long to build a feature because there's a different convention used in every corner of this monolithic application!

The core problem seems obvious, despite only really looking where the light is. And the solution is to adopt a well-organized, scalable, microservice architecture. And so, you're off to build it a better way, free of the baggage of the past, and filled with a renewed sense of confidence.

Same Story, Different Pattern

We know how the story goes from here. The cycle continues, and some version of the same story repeats itself, just with new characters on a different stage.

Bob Martin touches on this cycle in Clean Architecture: "The same overconfidence that led to the mess is now telling them that they can build it better if they can start the race over." Been there, by the way. Many, many times.

In fairness, blowing it up and pivoting to a new architecture might be a legitimately good decision. But it's a costly one, and it risks overlooking more subtle, meaningful problems we didn’t (want to) identify when the pain was fresh. A few come to mind: poor testing habits, squishy pattern standards, siloed relationships between stakeholders and engineers, uninvested team members, an otherwise unhealthy engineering culture, etc. Some of these are pretty boring, but they’ll cause a system to rot no matter how immaculate the architectural vision is.

All that said, think of this as another reminder of how important it is to be really clear on what it is we’re trying to solve, and why we think massive undertakings (like an architectural migration) have a realistic chance of helping. And when you hear that case being made, consider it your responsibility to press into it. Ask questions. Question assumptions. Leave no doubt that there aren’t other avenues more appropriate to explore, at least first.

It could end up being the right move. But at least not because we’re just eager to ride the pendulum as it swings to the other side (sorry, another metaphor).

patterns Article's
30 articles in total
Favicon
Streamlining Data Flow in Angular: The Power of the Adapter Pattern 🔄
Favicon
CQRS — Command Query Responsibility Segregation — A Java, Spring, SpringBoot, and Axon Example
Favicon
Mastering the Container-Presenter Pattern in Angular: A Deep Dive
Favicon
Repository Design Pattern, Promoting Packages via ADS, and New Arabic Article ✨
Favicon
Flexibilidad y Escalabilidad: Usando Strategy y Factory Patterns
Favicon
Understanding Domain Events in TypeScript: Making Events Work for You
Favicon
Padrões de Projeto em React [HOCs, Render Props, Hooks]
Favicon
Mobile Development Platforms and software architecture pattern in mobile development
Favicon
Finite-state machine example in JavaScript
Favicon
OOP Simplified: Quick Factory Methods with Encapsulation, Abstraction, and Polymorphism in TypeScript
Favicon
Finite-state machine example in JavaScript
Favicon
How to avoid N + 1 and keep your Ruby on Rails controller clean
Favicon
Types Of Software Architecture
Favicon
Testando das trincheiras: Usando um "clock" fixo
Favicon
¿POR QUÉ no estás usando estos providers de Angular?
Favicon
Common and Useful Deployment Patterns
Favicon
Reusing state management: HOC vs Hook
Favicon
Understanding JavaScript Creational Patterns for Object Creation
Favicon
Understanding Design First: Principles, Patterns, and Best Practices Explained
Favicon
The Architecture Might Not Be the Problem
Favicon
Padrão JumpTable com Javascript
Favicon
Explorando os Fundamentos dos Padrões de Projeto: Conceitos Básicos
Favicon
Six Factors That Raise The Risk Of Bugs In A Codebase
Favicon
Microservices: Avoiding the Pitfalls, Embracing the Potential - A Guide to Anti-Patterns
Favicon
Android Presentation Patterns: MVI
Favicon
Entendendo o Pub/Sub com Javascript
Favicon
The Consumer Conundrum: Navigating Change in Microservices Without Gridlock
Favicon
𝗪𝗵𝗮𝘁 𝗮𝗿𝗲 𝘁𝗵𝗲 𝗥𝗲𝗴𝗘𝘅 𝗣𝗮𝘁𝘁𝗲𝗿𝗻𝘀?
Favicon
Using a Trait in Builder CLIs
Favicon
CLI Contexts

Featured ones: