You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesi贸n a prueba de IA

Antes: $249

Currency
$209
Suscr铆bete

Termina en:

0 D铆as
12 Hrs
41 Min
20 Seg

Implementando el Patr贸n Observer

24/27
Resources

How to implement the Observer pattern in a payment system?

Implementing the Observer pattern in a payment system significantly improves the system's ability to react to events such as successful and failed payments. This approach allows us to send automatic notifications to relevant systems when specific transactions occur. In this class, we will break down how to set up this pattern in Python, following the proper steps to promote code scalability and maintainability.

How is the Listener protocol defined in Python?

The first step in implementing the Observer pattern is to define the protocol that acts as an interface to the Listeners. In Python, we can create this protocol using the typing module.

from typing import Protocol, TypeVar
 T = TypeVar('T')
class Listener(Protocol[T]): def notify(self, event: T)-> None: pass

This simple protocol forces concrete Listeners to implement the notify method, which will take an event of generic type T, not returning any value.

How do we handle Listeners?

The next step is to create a Listeners handler, which will allow Listeners to subscribe, unsubscribe and receive notifications.

from typing import Listfrom dataclasses import dataclass, field
 @dataclassclass ListenersManager: listeners: List[Listener] = field(default_factory=list)
 def subscribe(self, listener: Listener)-> None: self.listeners.append(listener)    
 def unsubscribe(self, listener: Listener)-> None: self.listeners.remove(listener)    
 def notify_all(self, event: T): for listener in self.listeners: listener.notify(event)

The ListenersManager acts as the mediator, taking care of adding and removing listeners and notifying events to all subscribed listeners.

How do we implement a specific Listener?

To demonstrate the practical use of the Observer pattern, we can create a specific Listener that notifies the accounting system about successful payments.

from listeners import Listener
class AccountabilityListener(Listener): def notify(self, event: T): print(f "Notifying the accounting system about the event: {event}")

This AccountabilityListener simply prints a notification message upon receiving an event.

How to integrate the Observer pattern in the main class?

Finally, we must adapt our main class to incorporate the ListenersManager and the specific Listeners we wish to use.

from listeners import ListenersManager, AccountabilityListener
class PaymentService: def __init__(self): self._listener_manager = ListenersManager() self._set_listeners()
 def _set_listeners(self): accountability_listener = AccountabilityListener() self._listener_manager.subscribe(accountability_listener)
 def process_transaction(self, payment_response): if payment_response.is_success: self._listener_manager.notify_all(f "Payment successful: {payment_response.transaction_id}") else: self._listener_manager.notify_all(f "Payment failed: {payment_response.transaction_id}")

In this example, the PaymentService class is responsible for handling notification events. During a successful or failed transaction, the service uses ListenersManager to notify all subscribed listeners.

What are the benefits of using the Observer pattern?

Using the Observer pattern provides several benefits:

  • Decoupling: event senders do not need to know the details of the listeners.
  • Scalability: It makes it easy to add new listeners without altering the existing code.
  • Reusability: Listeners can be reused in different areas of the application.

Integrating the Observer pattern into your payment system not only improves code organization and flow, but also increases efficiency in event handling. Keep exploring and learning more about design patterns to take your programming to the next level!

Contributions 2

Questions 2

Sort by:

Want to see more contributions, questions and answers from the community?

Implementar el \*\*Patr贸n Observer\*\* implica crear un sistema donde un objeto central (*\*subject\**) notifica autom谩ticamente a varios objetos suscritos (*\*observers\**) cada vez que su estado cambia. Veamos c贸mo implementarlo paso a paso en Python. \### Escenario: Sistema de Notificaciones para Pedidos Vamos a construir un ejemplo donde un sistema de pedidos notifica a varios servicios (correo electr贸nico, SMS, registro en el log) cuando se procesa un pedido. \### Paso 1: Crear el Subject El *\*subject\** gestiona la lista de *\*observers\** y los notifica cuando ocurre un cambio. ```pythonclass Subject:聽 聽 def \_\_init\_\_(self):聽 聽 聽 聽 self.\_observers = \[] 聽 聽 def attach(self, observer):聽 聽 聽 聽 """Suscribe un observer al subject."""聽 聽 聽 聽 self.\_observers.append(observer) 聽 聽 def detach(self, observer):聽 聽 聽 聽 """Elimina un observer del subject."""聽 聽 聽 聽 self.\_observers.remove(observer) 聽 聽 def notify(self, message):聽 聽 聽 聽 """Notifica a todos los observers."""聽 聽 聽 聽 for observer in self.\_observers:聽 聽 聽 聽 聽 聽 observer.update(message)``` \### Paso 2: Crear la Interfaz del Observer Define una clase base para los *\*observers\**. Esto asegura que todos implementen el m茅todo `update`. ```pythonfrom abc import ABC, abstractmethod class Observer(ABC):聽 聽 @abstractmethod聽 聽 def update(self, message):聽 聽 聽 聽 """Define c贸mo reaccionar谩 el observer al mensaje."""聽 聽 聽 聽 pass``` \### Paso 3: Crear Observers Concretos Cada *\*observer\** define su propia implementaci贸n del m茅todo `update`. ```pythonclass EmailNotifier(Observer):聽 聽 def update(self, message):聽 聽 聽 聽 print(f"EmailNotifier: Enviando email con el mensaje: '{message}'") class SMSNotifier(Observer):聽 聽 def update(self, message):聽 聽 聽 聽 print(f"SMSNotifier: Enviando SMS con el mensaje: '{message}'") class LogNotifier(Observer):聽 聽 def update(self, message):聽 聽 聽 聽 print(f"LogNotifier: Registrando en el log: '{message}'")``` \### Paso 4: Crear un Subject Concreto Crea una clase que represente el *\*subject\**. En este caso, un sistema de pedidos. ```pythonclass OrderSystem(Subject):聽 聽 def process\_order(self, order\_id):聽 聽 聽 聽 print(f"Procesando pedido {order\_id}...")聽 聽 聽 聽 self.notify(f"Pedido {order\_id} ha sido procesado con 茅xito.")``` \### Paso 5: Integrar Todo Conecta los *\*observers\** al *\*subject\** y prueba el sistema. ```python# Crear el sistema de pedidosorder\_system = OrderSystem() \# Crear los observersemail\_notifier = EmailNotifier()sms\_notifier = SMSNotifier()log\_notifier = LogNotifier() \# Suscribir los observers al sistema de pedidosorder\_system.attach(email\_notifier)order\_system.attach(sms\_notifier)order\_system.attach(log\_notifier) \# Procesar un pedidoorder\_system.process\_order("12345") \# Eliminar un observerorder\_system.detach(sms\_notifier) \# Procesar otro pedidoorder\_system.process\_order("67890")``` \### Salida Esperada \*\*Primer pedido (todos los observers suscritos):\*\* ```Procesando pedido 12345...EmailNotifier: Enviando email con el mensaje: 'Pedido 12345 ha sido procesado con 茅xito.'SMSNotifier: Enviando SMS con el mensaje: 'Pedido 12345 ha sido procesado con 茅xito.'LogNotifier: Registrando en el log: 'Pedido 12345 ha sido procesado con 茅xito.'``` \*\*Segundo pedido (SMSNotifier eliminado):\*\* ```Procesando pedido 67890...EmailNotifier: Enviando email con el mensaje: 'Pedido 67890 ha sido procesado con 茅xito.'LogNotifier: Registrando en el log: 'Pedido 67890 ha sido procesado con 茅xito.'``` \### Ventajas del Patr贸n Observer 1\. \*\*Desacoplamiento\*\*: Los *\*subjects\** no necesitan saber c贸mo funcionan los *\*observers\**.2. \*\*Flexibilidad\*\*: Puedes a帽adir o eliminar *\*observers\** din谩micamente.3. \*\*Reutilizaci贸n\*\*: Los *\*observers\** son reutilizables en diferentes sistemas. \### Casos de Uso Reales \- \*\*Interfaces gr谩ficas de usuario\*\*: Actualizaci贸n de vistas cuando el modelo cambia.- \*\*Sistemas de eventos\*\*: Publicaci贸n/suscripci贸n (*\*pub-sub\**), como en servicios de mensajer铆a.- \*\*Notificaciones en tiempo real\*\*: Alertas en aplicaciones. \### Conclusi贸n El \*\*Patr贸n Observer\*\* es ideal para sistemas en los que un cambio en un objeto afecta a otros. Su implementaci贸n en Python es directa y altamente extensible, lo que lo hace una herramienta poderosa para sistemas desacoplados y din谩micos.
El `[T]` en `AccountabilityListener` indica que es un tipo gen茅rico que permite que el listener reciba eventos de cualquier tipo. Esto es diferente de la herencia, que crea una relaci贸n entre clases, permitiendo que una clase derive de otra. Un ejemplo simple ser铆a: ```python from typing import TypeVar, Generic T = TypeVar('T') class EventListener(Generic[T]): def notify(self, event: T): print(f"Evento recibido: {event}") class StringListener(EventListener[str]): def notify(self, event: str): print(f"Cadena recibida: {event}") listener = StringListener() listener.notify("Hola, mundo!") # Salida: Cadena recibida: Hola, mundo! ``` Aqu铆, `EventListener` es gen茅rico y `StringListener` hereda de 茅l, definiendo que solo aceptar谩 cadenas.