Saltar al contenido

Arquitectura de la Aplicación

Cómo organizar el código dentro de cada aplicación: slicing horizontal (by layer) vs. vertical (by feature), y arquitecturas domain-centric —Hexagonal, Onion, Clean— para que las reglas de negocio no queden acopladas a la infraestructura.

6 min. de lectura

Una vez definida la estructura del sistema, todavía queda una pregunta:

¿Cómo organizamos el código dentro de cada aplicación o módulo?

Aquí aparecen dos ideas diferentes: Slicing Strategies y Domain-Centric Architecture.

Slicing Strategies

Una estrategia de slicing decide cómo dividir el código: de forma Horizontal o Vertical.

By Layer — Horizontal Slicing

Organiza el código según responsabilidades técnicas:

payments/
├── controllers/
├── services/
├── repositories/
├── entities/
└── dto/

El flujo típico de una request es:

Supongamos que necesitamos agregar Refund Payment. Probablemente terminemos modificando RefundController, PaymentService, PaymentRepository, PaymentEntity y RefundDTO. La funcionalidad queda repartida horizontalmente.

Ventaja

Es simple de entender y puede funcionar muy bien en aplicaciones pequeñas.

Problema

A medida que crecen las features, disminuye la feature locality:

Un cambio de negocio obliga a recorrer muchas partes de la estructura.

By Feature / Vertical Slice

Vertical Slice reorganiza el código en torno a funcionalidades o use cases:

payments/

├── authorize-payment/
│   ├── endpoint
│   ├── validator
│   ├── handler
│   └── repository

├── capture-payment/
│   ├── endpoint
│   ├── validator
│   ├── handler
│   └── repository

└── refund-payment/
    ├── endpoint
    ├── validator
    ├── handler
    └── repository

Una feature puede atravesar todas las capas necesarias:

La ventaja principal es la localidad del cambio: cuando cambia Refund Payment, gran parte del trabajo queda concentrada en un mismo lugar.

Vertical Slice no es CQRS

Pueden combinarse Vertical Slice, CQRS y DDD, pero son conceptos diferentes. Vertical Slice describe principalmente cómo organizamos el código. CQRS separa responsabilidades de commands y queries.

Vertical Slice tampoco reemplaza la inversión de dependencias

Una aplicación puede combinar Vertical Slice con Hexagonal Architecture:

refund-payment/
├── RefundPaymentHandler
├── RefundPaymentValidator
├── RefundPaymentController
└── RefundPaymentPort

mientras los adapters concretos quedan en infrastructure.

Referencia principal

Jimmy Bogard popularizó el término Vertical Slice Architecture para referirse a organizar las aplicaciones en torno a funcionalidades en lugar de capas técnicas. Vertical Slice Architecture — Jimmy Bogard.

Domain-Centric Architecture

Las estrategias de slicing responden “¿cómo organizamos el código?”. Hexagonal, Onion y Clean ponen el énfasis en otra pregunta:

¿Cómo evitamos que las reglas del negocio queden acopladas a los detalles de infraestructura?

El objetivo es que el core sea relativamente independiente de Database, HTTP, Framework, Message Broker, Cloud Provider y External APIs.

Hexagonal Architecture

Las arquitecturas domain-centric son, en el fondo, el Principio de Inversión de Dependencias aplicado a la escala de una aplicación entera: el dominio define los puertos y la infraestructura los implementa, de modo que la flecha de dependencia apunta siempre hacia adentro.

También llamada Puertos y Adaptadores.

El core define puertos; los adapters implementan esos puertos:

PaymentRepository

        │ implements

PostgresPaymentRepository

Esto evita que el dominio conozca PostgreSQL.

Ejemplo

Domain
  └── PaymentRepository

Infrastructure
  └── PostgresPaymentRepository

La aplicación puede reemplazar PostgreSQL por otro almacenamiento sin modificar las reglas principales del dominio.

Onion Architecture

La idea fundamental es que las dependencias apunten hacia el centro:

El domain es el núcleo.

Clean Architecture

Clean Architecture propone un enfoque similar:

Su regla fundamental es:

Las dependencias deben apuntar hacia adentro.

El dominio no debería depender de Spring, Hibernate, PostgreSQL, Kafka, AWS o HTTP. Esas tecnologías pueden depender de las abstracciones definidas por el core.

Hexagonal vs. Onion vs. Clean

Son conceptualmente cercanas:

EstiloIdea central
HexagonalPuertos y Adaptadores
OnionLas dependencias apuntan hacia adentro
CleanRegla de dependencia + casos de uso + límites

No conviene tratarlas como tres soluciones completamente diferentes. En una aplicación real pueden incluso combinarse ideas de las tres.

Cuándo usar Domain-Centric Architecture

Tiene mucho sentido cuando:

  • el dominio tiene reglas complejas;
  • el sistema debe sobrevivir a cambios de infraestructura;
  • se quiere testear la lógica de negocio de forma aislada;
  • existen múltiples adaptadores;
  • la aplicación tendrá una vida larga.

Cuándo evitarla

Para una aplicación muy sencilla (GET /products, POST /products), introducir cinco capas, múltiples puertos y una estructura enterprise puede agregar complejidad sin beneficio suficiente.

Tecnologías habituales

Este enfoque aparece frecuentemente en Spring Boot, .NET, NestJS, Kotlin, Java y TypeScript. El framework no determina la arquitectura.

Te sirvió, compartilo

// ¿te sirvió?
// compartilo