Introducción al curso
Saca el máximo provecho al curso con las recomendaciones de un experto
Conceptos detrás de las Arquitecturas Limpias
¿Qué son las arquitecturas limpias?
Características comunes de arquitecturas limpias
Cuándo aplicar y cuándo ignorar este tipo de arquitecturas
Principios de diseño
Arquitecturas de referencia
Arquitectura Hexagonal
Arquitectura Cebolla
Clean Architecture
Ejemplos del mundo real
Consideraciones sobre las arquitecturas hexagonal, cebolla y clean architecture
Dominio de una arquitectura
Detalles sobre el dominio
Organizando el dominio con un script de transacción
Inyección de dependencias
Modelo de Dominio
Capa de Servicios
Casos de Uso
CQRS
Capa externa
Acceso a Datos
Patrón Repository
Aplicaciones web y APIs
Integraciones y patrón Adapter
Pruebas
Dobles de prueba (pruebas de integración)
Cierre
Desafíos comunes
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
En el mundo del desarrollo de software, siempre buscamos herramientas y técnicas que nos ayuden a manejar de manera más eficiente nuestros sistemas y aplicaciones. Aquí es donde entra CQRS (Command Query Responsibility Segregation), una técnica que puede cambiar por completo la manera en que manejamos nuestras operaciones de lectura y escritura dentro de una aplicación.
CQRS, o Segregación de Responsabilidades de Comandos y Consultas, se basa en la idea de separar las operaciones que alteran el estado del sistema de aquellas que simplemente consultan datos. Esto se traduce en dos componentes principales:
Comandos: Operaciones de escritura que cambian el estado de algún objeto o sistema. Por ejemplo, guardar un usuario o modificar un atributo de una base de datos.
Consultas: Operaciones de lectura que se encargan de recuperar información, como "dame todos los usuarios registrados en los últimos 30 días" o "obtén la fecha de la última venta".
Al separar estos componentes, logramos una estructura más eficiente y sencilla de mantener, especialmente en aplicaciones que necesitan escalar.
Hay diversas razones para adoptar CQRS:
Escalabilidad: Algunas aplicaciones pueden requerir una administración más intensiva de las operaciones de lectura o escritura. Separando estas operaciones, cada componente puede escalar independientemente según las necesidades del sistema.
Mantenimiento: La separación de responsabilidades generalmente lleva a un código más limpio y comprensible, facilitando el mantenimiento de la aplicación a largo plazo.
Desempeño: Permite optimizar componentes específicos de acuerdo a su función principal (leer o escribir), mejorando el rendimiento general.
CQRS se podría implementar en C# utilizando una estructura de proyecto predefinida que enfatice las arquitecturas limpias. Por ejemplo:
public class CreateTodoListCommand : IRequest
{
public string Title { get; set; }
}
// Handler para el comando CreateTodoList
public class CreateTodoListCommandHandler : IRequestHandler<CreateTodoListCommand, Result>
{
private readonly TodoDbContext _context;
public CreateTodoListCommandHandler(TodoDbContext context)
{
_context = context;
}
public async Task<Result> Handle(CreateTodoListCommand request, CancellationToken cancellationToken)
{
var todoList = new TodoList { Title = request.Title };
_context.TodoLists.Add(todoList);
await _context.SaveChangesAsync(cancellationToken);
return Result.Success(todoList.Id);
}
}
En este ejemplo, el comando CreateTodoListCommand
está diseñado específicamente para manejar la operación de creación de una lista de tareas, utilizando Entity Framework para interactuar con la base de datos.
Las consultas se manejan de manera similar, pero se enfocan únicamente en recuperar datos:
public class GetTodosQuery : IRequest<IList<TodoList>>
{
}
public class GetTodosQueryHandler : IRequestHandler<GetTodosQuery, IList<TodoList>>
{
private readonly TodoDbContext _context;
public GetTodosQueryHandler(TodoDbContext context)
{
_context = context;
}
public async Task<IList<TodoList>> Handle(GetTodosQuery request, CancellationToken cancellationToken)
{
return await _context.TodoLists.ToListAsync(cancellationToken);
}
}
Este patrón asegura que el código esté limpio y que cada clase tenga una sola responsabilidad, mejorando la mantenibilidad y legibilidad del código.
En una arquitectura que adopta CQRS, los controladores (en una API, por ejemplo) no interactúan directamente con las consultas o comandos. En lugar de eso, utilizan un mediador que maneja los eventos y consultas:
[HttpGet]
public async Task<ActionResult<IList<TodoList>>> GetTodos()
{
var query = new GetTodosQuery();
var result = await _mediator.Send(query);
return Ok(result);
}
El uso de un framework como Mediator permite lanzar eventos para manejar consultas y comandos, promoviendo un desacoplamiento significativo entre las capas de la aplicación.
Además de operaciones dentro del código, CQRS se puede expandir a:
En escenarios más avanzados, incluso se puede aplicar CQRS a nivel de bases de datos, separando bases de datos dedicadas a operaciones de lectura y escritura, lo cual sería beneficioso en entornos de alta concurrencia.
Implementar CQRS es un paso importante hacia una arquitectura de software más robusta y escalable. Con un poco de práctica, verás cómo esta técnica puede transformar tu forma de desarrollar aplicaciones. ¡Anímate a investigar más sobre este tema y sigue aprendiendo!
Aportes 8
Preguntas 2
Considero que lo mas importante es no confundir a CQRS con la separacion de base de datos de escritura y lectura eso es mas bien lo que puede hacer el repository o un sistema de replica de base datos. Si no mas bien que separa la escritura de la lectura y esto es muy importante ya que en la escritura usualmente consumimos casos de uso y el dominio por lo cual hay validaciones en la lectura es util que no existan validaciones porque algunas veces por ejemplo se cambia a una arquitectura limpia pero se debe mantener el código legacy por tanto puede que exista data “sucia”
Command Query Reponsability Segregation
Se divide en comandos y consultas.
Comandos
Consultas
Esta idea se puede aplicar a varios niveles:
**Carpeta “Application”: **Contiene la lógica de aplicación y los casos de uso del sistema.
Carpeta “Domain”: Contiene las entidades, objetos de valor y reglas de dominio del sistema.
Carpeta “Infrastructure”: Contiene la implementación de infraestructura y servicios externos.
Carpeta “Persistence”: Contiene la lógica de persistencia y acceso a datos.
**Archivo “Colour.cs”: **Este archivo, ubicado en la carpeta “Domain/ValueObjects”, representa la clase Colour que define un objeto de valor para representar colores en el dominio del sistema. El archivo define métodos y propiedades relacionados con los colores, como la creación de instancias de colores, conversiones implícitas y explícitas a cadenas, y la lista de colores compatibles. También se definen constantes para colores comunes como blanco, rojo, naranja, amarillo, verde, azul, morado y gris.
✅
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?