Introducción a la clase
Vertical Slice Architecture organiza la aplicación por funcionalidades en lugar de capas horizontales, permitiendo que cada módulo sea independiente y contenga todo lo necesario para operar.
En esta clase aprenderás:
- Qué es Vertical Slice Architecture y cómo funciona
- Diferencias con Clean Architecture y Hexagonal Architecture
- Ventajas y desventajas de este enfoque
- Un ejemplo básico en C#
¿Qué es Vertical Slice Architecture?
En lugar de organizar el código en capas horizontales como Presentación, Aplicación, Dominio e Infraestructura, cada funcionalidad es un módulo independiente (Slice).
Estructura tradicional en capas:
Presentación (Controladores, UI)
--------------------------------
Aplicación (Casos de Uso, Servicios)
--------------------------------
Dominio (Entidades, Value Objects)
--------------------------------
Infraestructura (Repositorios, DB)
Estructura de Vertical Slice Architecture:
Crear Pedido (Controller, UseCase, DB)
--------------------------------------
Obtener Pedido (Controller, UseCase, DB)
--------------------------------------
Cancelar Pedido (Controller, UseCase, DB)
Diferencias con Clean Architecture y Hexagonal Architecture
- Clean Architecture → Separa la aplicación en capas concéntricas con reglas estrictas de dependencia.
- Hexagonal Architecture → Usa Puertos y Adaptadores para desacoplar el dominio de la infraestructura.
- Vertical Slice Architecture → Divide la aplicación en módulos funcionales independientes.
Característica | Clean Architecture | Hexagonal Architecture | Vertical Slice Architecture |
---|---|---|---|
Organización | Capas horizontales | Núcleo + Adaptadores | Funcionalidades independientes |
Acoplamiento | Bajo | Muy bajo | Casi inexistente |
Escalabilidad | Alta | Alta | Muy alta |
Mantenibilidad | Alta | Alta | Muy alta |
Complejidad | Media-Alta | Media-Alta | Media-Baja |
Mejor para | Aplicaciones grandes y mantenibles | Aplicaciones con múltiples integraciones | Aplicaciones modulares |
Ventajas de Vertical Slice Architecture
- Separación total de funcionalidades → Cada Slice es independiente.
- Facilita el mantenimiento → Modificar una funcionalidad no afecta otras.
- Escalabilidad modular → Se pueden agregar nuevas funcionalidades sin tocar el resto del código.
- Menos código innecesario → Evita capas de abstracción innecesarias.
- Ideal para microservicios → Cada Slice puede convertirse en un microservicio.
Desventajas de Vertical Slice Architecture
- Duplicación de código → Algunas funcionalidades pueden repetirse en distintos Slices.
- No es ideal para proyectos pequeños → Puede ser más simple usar Clean Architecture.
- Requiere una buena organización → Si no se maneja bien, puede volverse difícil de entender.
Ejemplo en C#: Implementando Vertical Slice Architecture
Cada Slice tendrá:
- Un Handler (Caso de Uso)
- Un Repositorio
- Un Controlador
Estructura del código:
/PedidosAPI
│── /Features
│ ├── /CrearPedido
│ │ ├── CrearPedidoCommand.cs
│ │ ├── CrearPedidoHandler.cs
│ │ ├── PedidoRepository.cs
│ │ ├── PedidoController.cs
│ ├── /ObtenerPedido
│ │ ├── ObtenerPedidoQuery.cs
│ │ ├── ObtenerPedidoHandler.cs
│ │ ├── PedidoRepository.cs
│ │ ├── PedidoController.cs
│── Program.cs
│── appsettings.json
Paso 1: Implementar el Slice «Crear Pedido»
Definir el comando (Request DTO)
public class CrearPedidoCommand
{
public string Cliente { get; set; }
public List<string> Productos { get; set; }
}
Implementar el Handler (Caso de Uso)
public class CrearPedidoHandler
{
private readonly PedidoRepository _repository;
public CrearPedidoHandler(PedidoRepository repository)
{
_repository = repository;
}
public void Handle(CrearPedidoCommand command)
{
var pedido = new Pedido(0, command.Cliente);
foreach (var producto in command.Productos)
{
pedido.AgregarProducto(new Producto(0, producto, 100)); // Precio por defecto
}
_repository.Guardar(pedido);
}
}
Implementar el Adaptador de Persistencia (Repositorio)
public class PedidoRepository
{
private readonly List<Pedido> _pedidos = new List<Pedido>();
public void Guardar(Pedido pedido)
{
_pedidos.Add(pedido);
}
}
Implementar el Controlador REST
[ApiController]
[Route("api/pedidos")]
public class PedidoController : ControllerBase
{
private readonly CrearPedidoHandler _crearPedidoHandler;
public PedidoController(CrearPedidoHandler crearPedidoHandler)
{
_crearPedidoHandler = crearPedidoHandler;
}
[HttpPost]
public IActionResult CrearPedido([FromBody] CrearPedidoCommand command)
{
_crearPedidoHandler.Handle(command);
return Ok("Pedido creado exitosamente");
}
}
Paso 2: Implementar el Slice «Obtener Pedido»
Definir la Query
public class ObtenerPedidoQuery
{
public int Id { get; set; }
}
Implementar el Handler (Caso de Uso)
public class ObtenerPedidoHandler
{
private readonly PedidoRepository _repository;
public ObtenerPedidoHandler(PedidoRepository repository)
{
_repository = repository;
}
public Pedido Handle(ObtenerPedidoQuery query)
{
return _repository.ObtenerPorId(query.Id);
}
}
Implementar el Controlador REST
[ApiController]
[Route("api/pedidos")]
public class PedidoController : ControllerBase
{
private readonly ObtenerPedidoHandler _obtenerPedidoHandler;
public PedidoController(ObtenerPedidoHandler obtenerPedidoHandler)
{
_obtenerPedidoHandler = obtenerPedidoHandler;
}
[HttpGet("{id}")]
public IActionResult ObtenerPedido(int id)
{
var pedido = _obtenerPedidoHandler.Handle(new ObtenerPedidoQuery { Id = id });
return pedido != null ? Ok(pedido) : NotFound();
}
}
Resumen de la Clase
- Vertical Slice Architecture organiza el código por funcionalidad en lugar de capas.
- Cada funcionalidad es un Slice independiente con su propia lógica.
- Facilita la modularidad y el desacoplamiento extremo.
- Ideal para sistemas que crecen rápidamente o para microservicios.
Próximo paso
En la siguiente clase veremos cómo separar las Features en lugar de las capas y cómo usar MediatR en Vertical Slice Architecture.