← Back to Clean Architecture

Clean Architecture

Screaming Architecture

A codebase that announces what it does before it announces what it runs on.

Clone a typical framework tutorial and the top of the source tree tells you what it runs on: Controllers, Views, Migrations. Clone a well-factored one and it should tell you what it is for. Robert C. Martin’s version of the test: a glance at the directory names should scream “shopping” or “health care,” not “Rails” or “ASP.NET.”

What the folder names announce

Open src/ApplicationCore/Entities in eShopOnWeb and this is what is there:

Entities/
  BasketAggregate/
    Basket.cs
    BasketItem.cs
  BuyerAggregate/
    Buyer.cs
    PaymentMethod.cs
  OrderAggregate/
    Address.cs
    CatalogItemOrdered.cs
    Order.cs
    OrderItem.csBasket, Buyer, and Order are the folders. They scream shopping, not Controllers or Migrations.
  CatalogBrand.cs
  CatalogItem.cs
  CatalogType.csCatalog nouns still name the business even when they are not wrapped in an aggregate folder.

No Controllers, no Migrations, nothing that names a framework. Basket, Buyer, Order, CatalogItem — the same nouns a product manager would use. Entities and Use Cases already showed why: everything inward of the interfaces is business rule, with no reason to mention ASP.NET, EF Core, or FastEndpoints.

What doesn’t scream, yet

Look one level higher, though, and the scream fades. The projects that make up the solution are named ApplicationCore, Infrastructure, PublicApi, Web — the layers from The Dependency Rule, not the business. Clone the repo and the very first thing you see is the architecture talking about itself.

That is a real trade-off, not a violation. The rule these layer names encode is what kept Web and Infrastructure out of ApplicationCore in the first place — see Interface Adapters and Frameworks & Drivers. One folder further in, past the layer boundary, is where the business actually lives, and it stays free of framework vocabulary the entire way down. The scream is delayed by one level, not silenced.

That is also what makes the last piece of this notebook possible: business rules that never import a framework can be exercised without one running. That is Testing Without Frameworks.