← Volver al blog
~/blog/clean-architecture-vs-screaming-architecture.md
Software Architecture

Clean Architecture vs Screaming Architecture: cómo estructurar un proyecto por casos de uso

Software Architecture
Best Practices

1 jun 2026- Sergio Zabala

Dos ideas, un mismo autor

Robert C. Martin (“Uncle Bob”) presentó ambos conceptos en su blog. En Screaming Architecture (2011) plantea una pregunta sencilla pero incómoda: si miras la estructura de carpetas de primer nivel de tu proyecto, ¿te dice qué hace la aplicación, o solo qué framework usa? Un año después, en The Clean Architecture (2012), formalizó las capas y reglas de dependencia que hacen posible ese tipo de estructura.

No son ideas que compitan entre sí: Screaming Architecture es el resultado visible de aplicar Clean Architecture correctamente. Una te dice por qué tus carpetas deberían verse de cierta forma; la otra te dice cómo llegar hasta ahí.

Screaming Architecture: lo que tus carpetas dicen de ti

La analogía de Martin es arquitectónica en el sentido literal: cuando miras los planos de un edificio, estos gritan “casa”, “biblioteca” o “estación de tren” sin que nadie te lo explique. Su reto a los desarrolladores es directo:

“Las arquitecturas no deberían venir dadas por los frameworks. Los frameworks son herramientas que se usan, no arquitecturas a las que hay que someterse.”

La mayoría de los proyectos no pasan esta prueba. Abre un proyecto típico de Node.js o Rails y lo primero que ves es controllers/, models/, services/, routes/: un organigrama de roles técnicos, no una descripción del negocio. No puedes saber si es un sistema de facturación o un blog hasta que bajas varios niveles de carpetas.

El punto de Martin es que el framework, la base de datos y la propia web son detalles: decisiones que deberían poder postergarse. Un sistema bien estructurado te permite decidir más tarde entre Express o Fastify, entre Postgres o Mongo, sin tocar la lógica de negocio.

Clean Architecture: el mecanismo detrás del grito

Clean Architecture aporta la estructura que hace posible ese aplazamiento, organizada en círculos concéntricos: Entities (reglas de negocio válidas para toda la empresa), Use Cases (lógica específica de la aplicación que orquesta a las entidades), Interface Adapters (controladores, presenters, gateways) y Frameworks & Drivers (frameworks web, bases de datos, UI: la capa más externa y volátil).

La regla que sostiene todo esto es la Dependency Rule: las dependencias del código fuente solo pueden apuntar hacia adentro. Los círculos internos nunca saben que los externos existen: un caso de uso no importa Express, y una entidad no sabe que Postgres existe. Como dice Martin, “la regla que hace que esta arquitectura funcione es la Dependency Rule”.

El beneficio es concreto: la lógica de negocio queda independiente de los frameworks, es testeable sin levantar una base de datos o un servidor HTTP, y permite cambiar la infraestructura —“puedes reemplazar Oracle o SQL Server por Mongo, BigTable, CouchDB o cualquier otra cosa”— sin reescribir el núcleo.

Antes: una estructura por capas técnicas

Un proyecto típico de Node/TypeScript organizado por capa técnica:

src/
  controllers/
    userController.ts
    orderController.ts
    invoiceController.ts
  services/
    userService.ts
    orderService.ts
    invoiceService.ts
  models/
    User.ts
    Order.ts
    Invoice.ts
  routes/
    userRoutes.ts
    orderRoutes.ts

Nada de esto grita “plataforma de e-commerce”. Para entender qué hace realmente el sistema —crear un pedido, emitir una factura, reembolsar a un cliente— hay que abrir varios archivos y reconstruir el flujo mentalmente. Añadir un caso de uso nuevo suele implicar tocar cuatro carpetas a la vez, y es fácil que detalles del framework (un Request de Express, un schema de Mongoose) se filtren directamente en lo que debería ser lógica de negocio pura.

Después: una estructura orientada a casos de uso

Reorganizado según lo que el sistema hace, siguiendo la Dependency Rule:

src/
  use-cases/
    place-order/
      PlaceOrder.ts
      PlaceOrder.test.ts
    issue-invoice/
      IssueInvoice.ts
      IssueInvoice.test.ts
    refund-customer/
      RefundCustomer.ts
  entities/
    Order.ts
    Invoice.ts
    Customer.ts
  interface-adapters/
    controllers/
      OrderController.ts
    gateways/
      OrderRepository.ts        # interfaz
  infrastructure/
    http/
      express/
        orderRoutes.ts
    persistence/
      postgres/
        PostgresOrderRepository.ts   # implementa OrderRepository

PlaceOrder.ts solo depende de las entidades Order y de una interfaz OrderRepository, nunca de Express o de Postgres. PostgresOrderRepository.ts vive en infrastructure/ e implementa esa interfaz. Si mañana cambias Express por Fastify, o Postgres por Mongo, use-cases/ y entities/ no cambian ni una línea. Abre la carpeta use-cases/ de primer nivel y el sistema te dice exactamente para qué sirve: crear pedidos, emitir facturas, reembolsar clientes, antes de haber leído una sola línea de implementación.

Cuándo vale la pena

Esto no sale gratis. Para una aplicación CRUD pequeña o un prototipo de vida corta, la indirección adicional (interfaces, inversión de dependencias, más carpetas) puede ser excesiva: estás pagando el costo de una estructura pensada para una flexibilidad que nunca vas a usar. Compensa cuando la lógica de negocio crece en complejidad y necesita sobrevivir a cambios de framework, múltiples mecanismos de entrega (web, CLI, procesos batch) o el mantenimiento a largo plazo por equipos que necesitan entender el proyecto leyendo nombres de carpetas, no rastreando imports.

Conclusión: deja que tu estructura hable

Clean Architecture y Screaming Architecture responden a dos preguntas distintas que llevan al mismo lugar. Clean Architecture pregunta “¿cómo mantengo la lógica de negocio independiente de la infraestructura?” y responde con capas y una regla de dependencia que apunta hacia adentro. Screaming Architecture pregunta “¿qué debería ver alguien al abrir mi proyecto?” y responde: tus casos de uso, no tu framework.

La prueba práctica es sencilla. Abre tu carpeta src/. Si lo primero que ves es controllers, services y models, tu arquitectura está gritando “aplicación web”. Si ves place-order, issue-invoice y refund-customer, está gritando lo que tu negocio realmente hace, y esa es la estructura que sobrevive a tu próxima migración de framework.