Para generar un código en C# aplicando patrones GoF y luego revisarlo, podemos seguir un flujo estructurado en el que primero se crea un ejemplo funcional y luego se realiza una mejora empleando principios de diseño y patrones adicionales. Aquí tienes un código base simple y a continuación exploraremos algunas mejoras.
El ejemplo gestiona notificaciones de diferentes tipos (SMS, Email, y Push). Este ejemplo puede beneficiarse del uso de patrones de diseño para manejar la creación de notificaciones y mejorar la escalabilidad y mantenibilidad del código.
using System;
namespace NotificationManager
{
public class NotificationService
{
public void SendNotification(string type, string message)
{
if (type == "SMS")
{
Console.WriteLine("Enviando SMS: " + message);
}
else if (type == "Email")
{
Console.WriteLine("Enviando Email: " + message);
}
else if (type == "Push")
{
Console.WriteLine("Enviando Notificación Push: " + message);
}
else
{
Console.WriteLine("Tipo de notificación no soportado");
}
}
}
class Program
{
static void Main(string[] args)
{
NotificationService notificationService = new NotificationService();
notificationService.SendNotification("SMS", "Mensaje de prueba para SMS");
notificationService.SendNotification("Email", "Mensaje de prueba para Email");
notificationService.SendNotification("Push", "Mensaje de prueba para Push");
notificationService.SendNotification("Fax", "Mensaje de prueba para Fax");
}
}
}- Código rígido: Agregar un nuevo tipo de notificación requiere modificar
SendNotification. - Violación de Principios SOLID:
- OCP (Open-Closed Principle): No es fácil extender la funcionalidad sin modificar el código existente.
- SRP (Single Responsibility Principle):
NotificationServicemaneja varios tipos de notificaciones y sus lógicas.
@startuml
abstract class Notification {
+Send(string message)
}
class SMSNotification extends Notification
class EmailNotification extends Notification
class PushNotification extends Notification
abstract class NotificationFactory {
+CreateNotification() : Notification
}
class SMSNotificationFactory extends NotificationFactory
class EmailNotificationFactory extends NotificationFactory
class PushNotificationFactory extends NotificationFactory
NotificationFactory <|-- SMSNotificationFactory
NotificationFactory <|-- EmailNotificationFactory
NotificationFactory <|-- PushNotificationFactory
Notification <|-- SMSNotification
Notification <|-- EmailNotification
Notification <|-- PushNotification
NotificationService --> NotificationFactory : usa
@enduml
Aquí tienes diez preguntas que podrías responder para guiarte en la mejora del código usando los patrones de diseño GoF:
-
¿Cómo podemos manejar tipos de notificación adicionales sin modificar la clase
NotificationService? Objetivo: Facilitar la escalabilidad de tipos de notificación (por ejemplo, Fax, WhatsApp) usando un patrón de creación, como Factory o Abstract Factory. -
¿Es la creación de instancias de
NotificationServiceeficiente o deberíamos implementar un patrón Singleton? Objetivo: Evaluar la necesidad de Singleton para reducir el consumo de recursos y evitar instancias redundantes deNotificationService. -
¿Qué patrón podemos usar para agregar características adicionales a las notificaciones, como logueo o almacenamiento en base de datos, sin modificar las clases existentes? Objetivo: Identificar si el patrón Decorator puede agregar comportamientos sin alterar el código base de las notificaciones.
-
¿Cómo podemos asegurar que las notificaciones se envíen en un orden específico o bajo ciertas condiciones? Objetivo: Considerar el uso del patrón Chain of Responsibility para decidir el orden de envío o manejar condiciones específicas para cada tipo de notificación.
-
¿Existen datos comunes que podrían encapsularse mejor usando un patrón de composición o agregación? Objetivo: Evaluar si el patrón Composite puede organizar mejor las notificaciones cuando hay datos o comportamientos comunes.
-
¿Podemos implementar una forma de deshacer el envío de una notificación? Objetivo: Explorar el uso del patrón Command para manejar comandos como "enviar" o "deshacer" una notificación y darle más flexibilidad a
NotificationService. -
¿Es posible generalizar los métodos de envío para reducir duplicación de código entre tipos de notificación? Objetivo: Investigar si patrones como Template Method o Strategy pueden ayudar a definir pasos comunes de envío de notificaciones en clases base.
-
¿Cómo se podría implementar un sistema de notificación más eficiente, en el que solo algunos usuarios reciban ciertas notificaciones? Objetivo: Aplicar el patrón Observer para que ciertos usuarios o suscriptores se notifiquen solo de ciertos eventos específicos, optimizando los envíos.
-
¿Deberíamos aplicar el patrón Facade para simplificar la interfaz de envío de notificaciones en
NotificationService? Objetivo: Considerar un Facade para ofrecer una interfaz simplificada y uniforme para el envío de notificaciones, ocultando la lógica compleja de los detalles internos. -
¿Cómo podríamos optimizar el uso de recursos cuando hay muchas notificaciones similares? Objetivo: Ver si el patrón Flyweight ayuda a reducir el uso de memoria en caso de que se creen muchas instancias de notificaciones con propiedades similares.
Responder estas preguntas te permitirá evaluar cada aspecto del sistema e identificar patrones de diseño que puedan mejorar la extensibilidad, eficiencia, mantenibilidad y organización del código.