Skip to content

Conversation

@dnovacovichh
Copy link

Análisis de la capa de entidades de dominio actual:

Clima:

Problemas detectados

  • Violación de SRP: Viola en principio de responsabilidad única al tener los detalles específicos de la Ubicación, Temperatura o Viento. Por ejemplo: Ciudad, región y país, podrían ser parte de una Clase llamada Ubicación.
  • Violación de Principio Abierto/Cerrado: Esto se hereda por haber violado el SRP. Si queremos agregar temperatura en Kelvin, tenemos que modificar la clase Clima.
    Lo mismo para Ubicacion.

Sobre atributos como pais o ciudad:

Actualmente modelados como String, lo cual puede generar inconsistencias. Deberían validarse o representarse con un objeto de valor o enumeración.

Se propone: Encapsular atributos en Ubicación, Temperatura y Viento.

De esta forma mejoramos:
- Mantenibilidad y desacoplamiento: Si tenemos que modificar algo de la Temperatura solo modificamos la clase Temperatura
- Extensibilidad: la clase Temperatura tiene Celsius y Kelvin. Seria sencillo agregar un atributo o método para tener la temperatura en Kelvin.

Email

Problemas detectados:

Violación de SRP: La clase Email tiene múltiples responsabilidades:

  • Contiene los datos del mensaje
  • Representa el estado del envío
  • Contiene lógica para enviar el mensaje

Falta de extensibilidad: Está acoplada al canal "email". Si se agregara WhatsApp, habría que modificar la lógica existente.

Estado enviado como booleano: No es expresivo ni suficiente. ¿Qué pasa si hubo un error en el envío?

Propuesta:

  • Crear una clase abstracta o base Notificacion
  • Utilizar un enum EstadoNotificacion con valores como: PENDIENTE, ENVIADO, RECHAZADO
  • Validar remitente y destinatario como correos electrónicos válidos

Rediseño de la capa de dominio

Antes:
Captura de pantalla 2025-05-25 220001

Después:
Captura de pantalla 2025-05-25 220033

Actualización la capa de servicios en función del nuevo diseño:

Se pueden hacer muchas mejoras en la capa de servicios:

ClimaService:

  • CIUDADES_ARGENTINA podría ser parametrizado para no tener que modificar ClimaService cuando queremos quitar o agregar una ciudad. (Atributo: Mantenibilidad)
  • Esta clase tiene demasiada responsabilidad y esta acomplada al Cliente Http WebClient. Incluso gestionamos la apiKey aca mismo (Atributo: SRP y acomplamiento)

Propuesta:

  • Crear la interfaz IClimaClient
  • Extraer el consumo de API a un cliente externo que pueda ser mockeado o sustituido fácilmente
  • Aplicar Inversión de Dependencias

AlertaService:

Problemas detectados:

  • Demasiada responsabilidad: (SRP)
    • Gestión de asincronismo (Mono)
    • Consulta de climas sin procesar
    • Evaluación de condición de alerta
    • Generar cuerpo del mail
    • Guardarlo para enviar
  • Está acoplado a las alertas por Mail. Si quisieramos agregar otros canales cómo por ejemplo, Whatsapp, no sería sencillo. (No es extensible)

Propuesta:

  1. Primero reduzcamos la responsabilidad: Creamos una abstracción IProcesadorDeAlertas que se va encargar de recibir Climas y generar alertas
    La responsabilidad que le queda a AlertaService es:

    • Gestión de asincronismo
    • Consulta de climas
    • Envío a procesar
  2. Implementamos el ProcesadorDeAlertas: En este punto para desacomplarnos del "Mail" vamos a crear una abstracción llamada "ICanalAlerta".

De ICanalAlerta esperamos que sepa evaluar un clima para saber si requiere alerta, y el guardado de la alerta para ser enviada.

  • boolean evaluar(Clima clima);
  • void guardarParaEnviar(Clima clima);

Ahora ProcesadorDeAlertas va a tener unas Lista de Canales de Alerta. La cual vamos a recorrer justo a los climas para alertar cuando sea necesario.

  1. Implementamos un canal de Alerta: AlertaMail

La cuál implementar evaluar cliema y guardarParaEnviar:

A Destacar:

  • La evaluación del clima para la alerta de la delegamos a AlertaPorTemperaturaYHumedad que hereda de CondicionAlerta.
  • La generación del cuerpo del mail se la delegamos a un GeneradorMensajeAlerta
  1. Gracias a este diseño, podemos agregar nuevos tipos de Alerta de manera sencilla. Ya que el ProcesadorDeAlertas utiliza ICanalAlerta y se abstrae de los detalles.

Podriamos crear AlertaWhatsapp, y hacer toda su implementación necesaria (Services, clients, etc) y para el Procesador es transparente.
Y no tendríamos que modificar ningun archivo relacionado directamente con el ProcesadorDeAlertas.

Resultado de Refactor:

  • Ahora el código es extensible a otros canales de notificación
  • Esta desacoplado de las implementaciones concretas de estos canales.
  • Respetamos los principios: SRP, OCP y DIP
  • Tenemos un código mucho más mantenible y testeable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant