Skip to content

Latest commit

 

History

History
144 lines (105 loc) · 5.36 KB

observer.md

File metadata and controls

144 lines (105 loc) · 5.36 KB

El patrón Observer

Con el patrón observer, podemos suscribir ciertos objetos, los observadores, a otro objeto llamado el observable. ¡Cada vez que ocurre un evento, el observable notifica a todos sus observadores!

Un patrón observer generalmente contiene 2 partes importantes:

  • Suscriptores: Un array de listeners que están suscritos a las notificaciones del notificador. Realizan la acción con la cual se subscribieron en respuesta a las notificaciones emitidas por el notificador. Todas estas clases deben implementar la misma interfaz de forma que el notificador no esté acoplado a clases concretas.
  • Notificador: Envía eventos de interés a otros objetos. Esos eventos ocurren cuando el notificador cambia su estado o ejecuta algunos comportamientos. Los notificadores también contienen una infraestructura de suscripción que permite a nuevos y antiguos suscriptores abandonar la lista.
    • subscribe(): un método para agregar suscriptores a la lista de suscriptores.
    • unsubscribe(): un método para eliminar suscriptores de la lista de suscriptores.
    • notify(): un método para notificar a todos los suscriptores cada vez que ocurre un evento específico.

Utilizar el patrón observador aporta varias ventajas:

  • Principio de abierto/cerrado. Puedes introducir nuevas clases suscriptoras sin tener que cambiar el código de la clase notificador (y viceversa si hay una interfaz notificador).
  • Puedes establecer relaciones entre objetos durante el tiempo de ejecución.

Usando el patrón observador

Puedes experimentar este problema a menudo al trabajar con clases de la interfaz gráfica de usuario. Por ejemplo, si creaste clases personalizadas de botón y quieres permitir al cliente colgar código cliente de tus botones para que se active cuando un usuario pulse un botón.

El patrón Observer permite que cualquier objeto que implemente la interfaz suscriptora pueda suscribirse a notificaciones de eventos en objetos observables o notificadores. Puedes añadir el mecanismo de suscripción a tus botones, permitiendo a los clientes acoplar su código personalizado a través de clases suscriptoras personalizadas.

Estructura

classDiagram
direction TB
    class Subscriber {
     +listen()
    }

    class Observer {
     - subscribers: Subscriber[]
     +subscribe(subscriber: Subscriber) void
     +unsubscribe(subscriber: Subscriber) void
     +notify(data: Data) : void
    }

    class SubscriberOne {
     +listen()
    }

    class SubscriberTwo {
     +listen()
    }

 <<Class>> Subscriber
 <<Class>> Observer
 <<Subscriber>> SubscriberOne
 <<Subscriber>> SubscriberTwo

    SubscriberOne --|> Subscriber : Inheritance
    SubscriberTwo --|> Subscriber : Inheritance
    Subscriber --> Observer : Association
    Observer ..|> SubscriberTwo : NotifyAllSubscribers
    Observer ..|> SubscriberOne : NotifyAllSubscribers
Loading

Ejemplo

interface Subscriber<D = string> {
  listen(data: D): void;
}

class Observer<D = string> {
  private subscribers: Subscriber<D>[] = [];

  constructor() {}

  public subscribe(subscriber: Subscriber<D>): void {
    this.subscribers.push(subscriber);
  }

  public unsubscribe(subscriber: Subscriber<D>): void {
    this.subscribers = this.subscribers.filter((s) => s !== subscriber);
  }

  public notify(data: D): void {
    this.subscribers.forEach((subscriber: Subscriber<D>) => {
      subscriber.listen(data);
    });
  }
}

class SubscriberOne implements Subscriber<string> {
  listen(data: string): void {
    console.log('LOG: One has been notified about: ' + data);
  }
}

class SubscriberTwo implements Subscriber<string> {
  listen(data: string): void {
    console.info('INFO: Two has been notified about: ' + data);
  }
}

const subscriberOne = new SubscriberOne();
const subscriberTwo = new SubscriberTwo();

const publisher = new Observer<string>();

publisher.subscribe(subscriberOne);
publisher.subscribe(subscriberTwo);

publisher.notify('Hello World!');

Output:

LOG: One has been notified about: Hello World!
INFO: Two has been notified about: Hello World!

Ejemplo en vivo

interface Subscriber<D = string> {
  listen(data: D): void;
}

class Observer<D = string> {
  private subscribers: Subscriber<D>[] = [];

  constructor() {}

  public subscribe(subscriber: Subscriber<...

Playground Link

Ejemplo de código

observer.ts