0

Estructuras de Datos en C# 11: Aplicación de algoritmos en Arquitectura Clean

Introducción a la clase

En esta clase exploraremos cómo estructuras de datos y algoritmos pueden aplicarse dentro del patrón de Clean Architecture. Aprenderemos cómo separar la lógica de negocio de los detalles de infraestructura para construir software escalable, modular y fácil de mantener.

¿Qué obtendrás de esta clase?

  • Comprender Clean Architecture y cómo los algoritmos encajan en esta estructura.
  • Aprender a utilizar estructuras de datos dentro de las capas de dominio, aplicación e infraestructura.
  • Implementar ejemplos prácticos con casos de uso reales.

Clean Architecture: Resumen rápido

Clean Architecture se basa en la separación de responsabilidades en capas:

  1. Capa de Entidades (Domain Layer): Contiene reglas de negocio y modelos de datos.
  2. Capa de Casos de Uso (Application Layer): Implementa lógica específica y algoritmos.
  3. Capa de Infraestructura (Infrastructure Layer): Contiene detalles como bases de datos y APIs.
  4. Capa de Presentación (UI Layer): Maneja la interacción con el usuario.

¿Dónde se aplican las estructuras de datos y algoritmos?

ComponenteAlgoritmos / Estructuras utilizadas
Capa de DominioÁrboles, listas, diccionarios para modelos y validaciones
Casos de UsoAlgoritmos de búsqueda, ordenación, programación dinámica
InfraestructuraIndexación con Hash Tables, Cache con Diccionarios
UI / APIManejo de colas y caché para optimizar respuestas

Ejemplo práctico: Gestión de pedidos en un sistema de e-commerce

Supongamos que estamos construyendo un sistema de gestión de pedidos donde los clientes pueden realizar compras y rastrear su estado.

Modelo de Dominio (Entidades y Reglas de Negocio)

public class Pedido
{
    public int Id { get; set; }
    public string Cliente { get; set; }
    public decimal Total { get; set; }
    public EstadoPedido Estado { get; private set; }

    public Pedido(int id, string cliente, decimal total)
    {
        Id = id;
        Cliente = cliente;
        Total = total;
        Estado = EstadoPedido.Pendiente;
    }

    public void MarcarComoEnviado()
    {
        if (Estado == EstadoPedido.Pendiente)
            Estado = EstadoPedido.Enviado;
    }
}

public enum EstadoPedido
{
    Pendiente,
    Enviado,
    Entregado
}

Aquí usamos una clase de dominio para manejar la lógica de negocio de los pedidos.

Caso de Uso: Procesar un Pedido (Aplicación Layer)

Los pedidos se almacenarán en una estructura de datos eficiente como un diccionario para facilitar su búsqueda.

using System;
using System.Collections.Generic;

public class ProcesarPedidoUseCase
{
    private readonly Dictionary<int, Pedido> _pedidos;

    public ProcesarPedidoUseCase()
    {
        _pedidos = new Dictionary<int, Pedido>();
    }

    public void AgregarPedido(Pedido pedido)
    {
        _pedidos[pedido.Id] = pedido;
    }

    public Pedido ObtenerPedido(int id)
    {
        return _pedidos.ContainsKey(id) ? _pedidos[id] : null;
    }

    public void EnviarPedido(int id)
    {
        if (_pedidos.ContainsKey(id))
            _pedidos[id].MarcarComoEnviado();
    }
}

class Program
{
    static void Main()
    {
        var procesarPedido = new ProcesarPedidoUseCase();
        
        procesarPedido.AgregarPedido(new Pedido(1, "Carlos", 150.99m));
        procesarPedido.AgregarPedido(new Pedido(2, "Ana", 320.50m));

        procesarPedido.EnviarPedido(1);
        Console.WriteLine($"Estado del pedido 1: {procesarPedido.ObtenerPedido(1).Estado}");
    }
}

Aquí usamos un diccionario (O(1)) para almacenar y buscar pedidos eficientemente.

Infraestructura: Base de Datos y Persistencia

Podemos implementar un repositorio para manejar el acceso a la base de datos.

using System.Collections.Generic;
using System.Linq;

public interface IPedidoRepositorio
{
    void Guardar(Pedido pedido);
    Pedido ObtenerPorId(int id);
}

public class PedidoRepositorio : IPedidoRepositorio
{
    private readonly List<Pedido> _pedidos = new List<Pedido>();

    public void Guardar(Pedido pedido)
    {
        _pedidos.Add(pedido);
    }

    public Pedido ObtenerPorId(int id)
    {
        return _pedidos.FirstOrDefault(p => p.Id == id);
    }
}

Aquí usamos una lista en memoria simulando una base de datos.

Caso de uso real

Un sistema de tracking de paquetes usa una cola de prioridad para procesar envíos urgentes primero.

Ejemplo en C#: Gestión de envíos con una Cola

using System;
using System.Collections.Generic;

class SistemaEnvios
{
    static void Main()
    {
        Queue<Pedido> colaEnvios = new Queue<Pedido>();

        colaEnvios.Enqueue(new Pedido(1, "Carlos", 150.99m));
        colaEnvios.Enqueue(new Pedido(2, "Ana", 320.50m));

        while (colaEnvios.Count > 0)
        {
            Pedido pedido = colaEnvios.Dequeue();
            Console.WriteLine($"Enviando pedido {pedido.Id} de {pedido.Cliente}");
        }
    }
}

Aquí usamos una cola FIFO para procesar envíos en orden de llegada.

Beneficios de integrar algoritmos en Clean Architecture

BeneficioExplicación
ModularidadLos algoritmos están separados en casos de uso específicos
ReutilizaciónLa lógica puede utilizarse en múltiples partes del sistema
EscalabilidadSe pueden intercambiar estructuras de datos según las necesidades
MantenimientoCódigo más claro y desacoplado

Desafío práctico

Ejercicio:

  1. Implementa un sistema de gestión de tareas donde cada tarea se almacene en una lista ordenada por prioridad.
  2. Modifica el sistema de pedidos para que los pedidos urgentes se procesen antes que los regulares (puedes usar una cola de prioridad).

Resumen de la clase

  • Clean Architecture separa la lógica en capas para mejorar la mantenibilidad.
  • Diccionarios, listas y colas se integran en los casos de uso para mejorar la eficiencia.
  • Casos de uso reales incluyen gestión de pedidos y envíos en e-commerce.

Próxima clase: Uso de estructuras de datos en Arquitectura Hexagonal

En la siguiente clase exploraremos cómo aplicar estructuras de datos dentro del patrón de Arquitectura Hexagonal, permitiendo que la lógica de negocio sea totalmente independiente de la infraestructura.

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *