Skip to content

Screaming Architecture: Not Driven By Entities

“Manager”, “Builder”, “Factory”, or another technical name in your code structure isn’t Screaming Architecture or Vertical Slices.

This post was inspired by the neverending posts I see on LinkedIn about software architecture styles and concepts. Let’s be real: The signal-to-noise ratio isn’t great, and many posts miss context and nuance. So, let’s unpack some thoughts on this.

YouTube

Check out my YouTube channel, where I post all kinds of content accompanying my posts, including this video showing everything in this post.

Vertical Slice Architecture

First up is the ever-popular vertical slice architecture, which seems to be widely misunderstood. One post I came across suggested that vertical slice architecture without domain-driven refactoring is just “spaghetti code” in use case slices.

The crux of vertical slice architecture is cohesion. It’s all about grouping capabilities that your system provides around business processes and workflows. It doesn’t matter if you’re building a monolith or microservices; without cohesion, you could end up with a giant mess.

The goal is to break that mess into manageable pieces—like turning a single turd pile into several smaller, more manageable ones. Nobody wants to build a big turd pile, right?

When organizing your code, you should think about isolation and boundaries. Within those boundaries, you can decide which capabilities to group together.

Whether you have a simple data model or a complex asynchronous-driven architecture, it’s all about determining what fits best for each use case.

A vertical slice can be thought of as a bounded context in Domain Driven Design at a higher level, but at a lover level and can be a single capability of a request. This allows you to define how you want to implement each vertical slice. In other words, not each vertical slice needs to adhere to the same patterns of every other.

In some vertical slices you might choose to use a domain model to manage complexity, in others it might be CRUD and you have a simple data model. Let your use case decide how to implement it.

Screaming Architecture

This leads us to the concept of screaming architecture. If your application’s folder structure consists solely of technical concerns—like API, models, views, controllers, DTOs, and databases—then your app doesn’t communicate anything about the problem it solves. It’s driven by technology rather than the domain. This can lead to maintenance hell, especially when you need to add new features.

So, your folder structure should communicate the domain, not the technology.

In the car rental example, while it’s a simple illustration, it doesn’t really tell us how to rent a car or what the process looks like.

An InvoiceGenerator is mentioned, but when is it used? UserManager, PaymentGateway, these all sound very technical still.

This is where organizing code around business processes and capabilities comes into play. It’s all about what your software actually does.

Business Capabilities vs. Entity Driven

A business capability defines an organization’s ability to perform a unique business activity. In another example I’ve discussed in a different blog—a dining party hosting system—there are a series of events and activities that take place: planning the dinner, reserving seats, confirming reservations, and hosting the actual dinner. The design of your system should be driven by these capabilities and activities rather than merely focusing on entities.

When you focus on entities, you risk creating unnecessary coupling between different parts of your system.

I love this tweet from Alberto because it really hits the nail on thehead. If you’re focusing on “entities” you’ll end up with a whole lot of coupling. In the example of the Dinner Party system, if we focus and build our system based on entities, we’ll end up with a highly coupled system that’s hard to change.

But if we focus on the workflows as I described earlier, we can model those workflows and then determine the entities involved in each. This means there is no singular concept of an entity, but rather what the entity represents within a workflow—ridding your system of “god” entities and reducing coupling.

The CRUD Debate

Now, let’s talk about CRUD. Someone recently commented that they’ve never encountered a CRUD case in their 15 years in the field. They emphasized that it’s always about workflows, business constraints, state machines, events, and push-based information.

For me, it’s a bit of both. At the heart of what I build, there is definitely CRUD involved, but it’s always wrapped around workflows and business constraints.

While many systems may be built solely around CRUD, that doesn’t mean they should be.

Join CodeOpinon!
Developer-level members of my Patreon or YouTube channel get access to a private Discord server to chat with other developers about Software Architecture and Design and access to source code for any working demo application I post on my blog or YouTube. Check out my Patreon or YouTube Membership for more info.

Leave a Reply

Your email address will not be published. Required fields are marked *