Implementación del Strategy Pattern en Procesador de Pagos en Python

Clase 16 de 27Curso de Patrones de Diseño y SOLID en Python

Resumen

¿Cómo se implementa el patrón de estrategia en un servicio de pagos de Python?

En este fascinante recorrido por el patrón de diseño "Strategy", nos enfocamos en su aplicación a un servicio de pagos en Python. Este patrón es ideal cuando estamos frente a múltiples soluciones que abordan un mismo tipo de problema, permitiéndonos cambiar las estrategias en tiempo de ejecución. En este caso, ayudaremos a entender cómo utilizar un atributo "notificador" dentro de una clase de "PaymentService" utilizando el patrón de estrategia.

¿Cómo modificar la estrategia en tiempo de ejecución?

Uno de los pasos esenciales para implementar el patrón de estrategia es crear un método que permita modificar la implementación de la estrategia durante la ejecución del programa. Aquí se define un método setNotifier dentro del servicio de pagos, donde:

  • El parámetro de este método es un "notificador" del tipo "Notifier protocol".
  • Simplemente se cambia el atributo del notificador dentro del objeto.
  • Se utiliza un print para indicar que la implementación del notificador ha cambiado.
def setNotifier(self, notifier: NotifierProtocol):
    self.notifier = notifier
    print("Cambiando la implementación del notificador.")

¿Cómo elegir la estrategia correcta?

Es vital tener una función que seleccione la estrategia correcta basándose en las condiciones del problema. En este caso, se crea getNotifierImplementation que:

  • Recibe como parámetro datos de un cliente.
  • Evalúa si los datos de contacto del cliente contienen un teléfono o un correo electrónico.
  • Selecciona la estrategia adecuada (envío por SMS o email) según la información proporcionada.
def getNotifierImplementation(customer_data: CustomerData) -> NotifierProtocol:
    if customer_data.contact_info.phone:
        return SMSNotifier(SMSGetwayMock())
    elif customer_data.contact_info.email:
        return EmailNotifier()
    else:
        raise ValueError("No se puede elegir la estrategia correcta.")

¿Cómo se define una función para manejar los datos del cliente?

Para lograr una correcta elección de estrategia, es esencial tener datos del cliente bien estructurados. Se recomienda definir una función get_customer_data que prepare estos datos:

  • Retorna un objeto CustomerData con información relevante como el nombre y el email.
  • Se utiliza para poblar los parámetros de getNotifierImplementation.
def get_customer_data() -> CustomerData:
    contact_info = ContactInfo(email="john.doe@mail.co")
    return CustomerData(name="John Doe", contact_info=contact_info)

¿Qué hacer si falla la estrategia seleccionada?

El cambio de estrategias en tiempo de ejecución permite adaptarse a situaciones inesperadas, como el fallo en el envío del correo. Un ejemplo de cómo podría ser gestionado es mediante:

  • Crear funciones específicas para obtener instancias de notificaciones de email o SMS.
  • Cambiar la estrategia utilizando service.setNotifier en caso de error con la estrategia actual.
def get_email_notifier() -> EmailNotifier:
    return EmailNotifier()

def get_sms_notifier() -> SMSNotifier:
    return SMSNotifier(SMSGetwayMock())

# Cambio manual de estrategia
try:
    # Ejecutar envío con notificador actual...
except:
    service.setNotifier(get_email_notifier())

¿Existen otros casos de uso del patrón de estrategia?

El patrón de estrategia no está limitado a servicios de notificación. Por ejemplo, también es posible aplicarlo en la selección de un procesador de pagos basado en el tipo de pago que se está manejando. Esta versatilidad convierte el patrón de estrategia en una herramienta poderosa para crear aplicaciones flexibles y extensibles en Python.

El camino por el mundo de los patrones de diseño es emocionante y promete grandes beneficios a quienes los dominan. La adopción del patrón de estrategia en proyectos personales o profesionales puede representar una mejora significativa en la capacidad de adaptación y gestión de código. Te invitamos a seguir explorando y experimentando con diferentes implementaciones para llevar tus habilidades a un nuevo nivel de excelencia.