Un modèle de conception est un modèle qui résout un problème récurrent dans la conception de logiciels.

Le modèle d'observateur, également appelé modèle de publication-abonnement, est un modèle comportemental. Il vous permet d'informer plusieurs objets ou abonnés de tout événement publié dans l'objet qu'ils observent.

Ici, vous apprendrez à implémenter le modèle de conception d'observateur dans TypeScript.

Le modèle d'observateur

Le modèle d'observateur fonctionne en définissant une relation un-à-plusieurs entre l'éditeur et ses abonnés. Lorsqu'un événement se produit dans l'éditeur, il avertit tous les abonnés à cet événement. Un exemple répandu de ce modèle est Écouteurs d'événements JavaScript.

Pour le contexte, supposons que vous construisez un outil de suivi des stocks qui suit le nombre de produits dans votre magasin. Dans ce cas, votre magasin est le sujet/éditeur, et votre inventaire est l'observateur/abonné. L'utilisation du modèle de conception d'observateur serait optimale dans cette situation.

instagram viewer

Dans le modèle de conception d'observateur, votre classe de sujet doit implémenter trois méthodes :

  • Un attacher méthode. Cette méthode ajoute un observateur au sujet.
  • UN détacher méthode. Cette méthode supprime un observateur d'un sujet.
  • UN notifier/mettre à jour méthode. Cette méthode avertit les observateurs du sujet lorsque l'état change dans le sujet.

Votre classe d'observateur doit implémenter une méthode, la mise à jour méthode. Cette méthode réagit lorsqu'il y a un changement dans l'état de son sujet.

Implémentation des classes de sujet et d'observateur

La première étape de l'implémentation de ce modèle consiste à créer des interfaces pour le sujet et la classe d'observateur, afin de s'assurer qu'ils implémentent les bonnes méthodes :

// Interface sujet/éditeur
interfaceSujet{
attachObserver (observateur: Observateur): annuler;
detachObserver (observateur: Observer): annuler;
notifierObserver(): annuler;
}

// Interface Observateur/Abonné
interfaceObservateur{
mise à jour(sujet: sujet): annuler;
}

Les interfaces du bloc de code ci-dessus définissent les méthodes que vos classes concrètes doivent implémenter.

Une classe de sujets concrets

L'étape suivante consiste à implémenter une classe de sujet concrète qui implémente le Sujet interface:

// Sujet
classeMagasinmet en oeuvreSujet{}

Ensuite, initialisez le Sujetl'état dans le Magasin classe. Les observateurs du sujet réagiront aux changements de cet état.

Dans ce cas, l'état est un nombre, et les observateurs réagiront à une augmentation du nombre :

// État du sujet
privé nombreDeProduits: nombre ;

Ensuite, initialisez un tableau d'observateurs. Ce tableau vous permet de suivre les observateurs :

// initialisation des observateurs
privé observateurs: Observateur[] = [] ;

Vous pouvez trouver des implémentations du modèle d'observateur en utilisant a Définir la structure des données à la place d'un tableau pour garder une trace de l'observateur. L'utilisation d'un ensemble garantira que le même observateur n'apparaîtra pas deux fois. Si vous souhaitez utiliser un tableau à la place, vous devez vérifier les observateurs en double dans votre attacher méthode.

Ensuite, vous devez implémenter le Sujetles méthodes de—attacher, détacher, et notifier/mettre à jour—dans votre classe concrète.

Pour mettre en œuvre le attacher, vérifiez d'abord si l'observateur est déjà attaché et lancez une erreur si c'est le cas. Sinon, ajoutez l'observateur au tableau en utilisant le Méthode de tableau JavaScript, pousser:

// Attachement d'observateur(s)
attachObserver (observateur: Observateur): annuler {
// Vérifie si l'observateur a déjà été attaché
constante observerExists = ce.observateurs.inclut (observateur) ;

si (observateurExists) {
lancernouveauErreur('Observer a déjà été abonné ');
}

// Ajouter un nouvel observateur
ce.observateurs.pousser(observateur);
}

Ensuite, mettez en œuvre votre détacher méthode en trouvant l'index et en le supprimant du tableau à l'aide de JavaScript épissure méthode.

Il peut y avoir des scénarios où l'observateur que vous essayez de détacher a déjà été détaché ou n'a pas été abonné en premier lieu. Vous devez gérer ces scénarios en ajoutant une instruction conditionnelle pour vérifier si l'observateur se trouve dans le tableau ou dans l'ensemble, selon le cas.

// Détachement d'observateur(s)
detachObserver (observateur: Observer): annuler {
console.enregistrer(`Détacher l'observateur ${JSON.stringify (observateur)}`);
constante indiceobservateur = ce.observers.indexOf (observateur);

si (observateurIndex -1) {
lancernouveauErreur("L'observateur n'existe pas");
}

ce.observateurs.épissure(observateurIndex, 1);
console.log('Observateur détaché...');
}

Ensuite, mettez en œuvre votre notifier/mettre à jour méthode en bouclant sur votre liste d'observateurs et en appelant la mise à jour méthode de chacun :

// Aviser les observateurs
notifierObserver(): annuler {
console.log('Aviser les observateurs...');

pour (constante observateur dece.observateurs) {
observateur.mise à jour(ce);
}
}

Enfin, pour le Sujet classe, implémentez une méthode qui manipule l'état, puis notifie les observateurs du changement en appelant leur notifier/mettre à jour méthode. Cet exemple est une simplification de la façon dont un sujet peut effectuer une action et ensuite informer les observateurs :

// Changement d'état et notification des observateurs
newProduct (produits: nombre): annuler {
ce.numberOfProducts += produits ;
console.log('Nouveau produit ajouté au magasin');
ce.notifyObserver();
}

Classes concrètes d'observateurs

Créez une ou plusieurs classes d'observateurs pour vous abonner à l'éditeur. Chaque classe d'observateur doit implémenter le Observateur interface.

Les classes d'observateurs mettront en œuvre un notifier/mettre à jour méthode que seul le sujet qu'ils observent devrait appeler. Cette méthode doit contenir toute la logique métier dont vous avez besoin pour exécuter en réponse à un changement d'état du sujet :

// Observateur concret 1
classeInventairemet en oeuvreObservateur{
mise à jour(): annuler {
console.log('Nouveau produit ajouté au magasin, mise à jour de l'inventaire...');
// La logique métier réelle va ici...
}
}

// Observateur concret 2
classeClientmet en oeuvreObservateur{
mise à jour(): annuler {
console.log('Nouveau produit ajouté au magasin, il faut que j'aille y jeter un œil...');
// La logique métier réelle va ici...
}
}

Utilisation du modèle d'observateur

Pour utiliser ce modèle, instanciez les classes concrètes de sujet et d'observateur. Une fois que vous avez fait cela, appelez le sujet attacher méthode et passez l'instance d'Observer en tant qu'argument. En réponse, le sujet ajoutera cette instance à sa liste d'observateurs :

// Instanciation du sujet et de l'observateur
constante magasin = nouveau Magasin();
constante inventaire = nouveau Inventaire();
constante client = nouveau Client()

// Souscription d'objets à l'éditeur
magasin.attachObserver(inventaire);
magasin.attachObserver(client);
// Modification de l'état du sujet
magasin.nouveau produit(30);

Ce code simule un changement d'état. Le changement déclenchera la méthode de notification sur le Sujet classe. Cette méthode, à son tour, appelle le notifier méthode sur chacun de ses observateurs. Chaque observateur exécutera alors sa propre logique métier.

Vous ne devez utiliser ce modèle que lorsque les changements d'état d'un objet affectent d'autres objets et que l'ensemble d'objets impliqués est inconnu ou dynamique.

Avantages de l'utilisation du modèle d'observateur

L'utilisation de ce modèle dans votre code vous permet de conserver le principe d'ouverture/fermeture. Vous pouvez ajouter autant d'abonnés que vous le souhaitez et établir des relations entre les objets lors de l'exécution, sans modifier le code du sujet.