Maison > développement back-end > tutoriel php > Comprendre le modèle d'observateur

Comprendre le modèle d'observateur

Jennifer Aniston
Libérer: 2025-02-28 09:14:19
original
992 Les gens l'ont consulté

Understanding the Observer Pattern

Points de base

  • Le modèle d'observateur est un modèle de conception comportemental qui établit une relation un-à-plusieurs entre les objets.
  • Ce mode contient un sujet (ou un éditeur) et un observateur (ou abonné). Le sujet informe l'observateur de tout changement de statut et l'observateur peut agir en conséquence. Ce mode favorise le couplage lâche, ce qui rend le système plus flexible et plus facile à modifier ou à développer.
  • La classe d'observateurs fournit une méthode
  • que le sujet appelle pour informer ses changements d'état. Les principales méthodes de définition des classes de sujets: update(), attach(), detach() et setState() sont utilisées pour gérer les observateurs et les informer des changements de statut. notify()
  • Le mode observateur convient aux situations où les modifications à un objet nécessitent des modifications d'autres objets, surtout si le nombre d'objets à modifier est inconnu. Il peut être utilisé pour maintenir la cohérence entre les objets associés sans les coupler étroitement. Par exemple, il est utilisé pour relier le mécanisme d'authentification du portail avec le logiciel Forum, permettant aux utilisateurs de se connecter aux deux avec une seule connexion.
On m'a récemment demandé d'intégrer un logiciel de forum tiers dans mon portail Web existant. Le problème est que les deux applications ont leurs propres mécanismes d'authentification indépendants. Du point de vue de l'utilisateur, idéalement, les utilisateurs peuvent se connecter au portail sans avoir à se connecter séparément au forum. Dans ce cas, je ne veux pas modifier le code du forum inutilement car cela crée un cauchemar de maintenance - je dois fusionner les mises à jour et les corrections de bogues ultérieures du fournisseur et veillez à éviter d'écraser mes propres modifications. C'est là que le mode observateur est très pratique pour moi. Dans cet article, je vais vous montrer comment implémenter le modèle d'observateur. Vous apprendrez comment diverses classes dans le modèle sont liées les unes aux autres en tant que sujets et observateurs, comment les sujets informent l'observateur des changements dans leur état et comment identifier des scénarios adaptés à l'utilisation du modèle d'observateur dans votre propre code.

Mode d'observateur

Modèle d'observateur (également connu sous le nom de Publish-Subscribe Pattern) est un modèle de conception comportemental qui définit les relations un à plusieurs entre les objets de sorte que lorsqu'un objet modifie son état, tous les objets dépendants sont automatiquement notifiés et mis à jour. Dans mon cas, j'ai utilisé ce mode pour relier le mécanisme d'authentification du portail avec le logiciel Forum. Le comportement de connexion au portail déclenchera également automatiquement l'utilisateur pour se connecter au forum. Les objets qui ont une relation un-à-plusieurs avec d'autres objets intéressés par leur propre état sont appelés

thème ou éditeur . Son objet de dépendance est appelé Observer ou l'abonné . Chaque fois que l'état du sujet change, l'observateur est informé et peut agir en conséquence. Un sujet peut avoir un certain nombre d'observateurs dépendants qui enverront des notifications à ces observateurs, et n'importe quel nombre d'observateurs peuvent souscrire au sujet pour recevoir de telles notifications.

Catégorie d'observateur La classe Observer fournit une méthode

que le sujet appellera pour informer ses modifications d'état. Dans cet exemple, j'ai défini la méthode update() comme une méthode spécifique. Si vous le souhaitez, vous pouvez définir la méthode comme une méthode abstraite ici, puis en fournir une implémentation concrète dans la sous-classe de l'observateur. update()

<?php
abstract class Observer
{
    public function __construct($subject = null) {
        if (is_object($subject) && $subject instanceof Subject) {
            $subject->attach($this);
        }
    }

    public function update($subject) {
        // 查找具有状态名称的观察者方法
        if (method_exists($this, $subject->getState())) {
            call_user_func_array(array($this, $subject->getState()), array($subject));
        }
    }
}
Copier après la connexion
Copier après la connexion

La méthode accepte les instances de sujets observables et s'attache au sujet - j'en parlerai plus tard. La méthode __construct() récupère l'état actuel du sujet et l'utilise pour invoquer une méthode d'observateur sous-classé avec le même nom d'état. Donc, dans mon cas spécifique, je dois faire la classe Auth existante du portail comme sujet observable et créer une sous-classe d'observateur concrète pour se connecter au code d'authentification du forum. Ma sous-classe doit également implémenter la méthode en utilisant l'état du sujet. update()

Catégorie de thème La classe d'objet est également une classe abstraite, qui définit quatre méthodes principales:

,

, attach(), detach() et setState(). Pour plus de commodité, j'ai également ajouté les méthodes notify() et getState() ici. getObservers()

<?php
abstract class Subject
{
    protected $observers;
    protected $state;

    public function __construct() {
        $this->observers = array();
        $this->state = null;
    }

    public function attach(Observer $observer) {
        $i = array_search($observer, $this->observers);
        if ($i === false) {
            $this->observers[] = $observer;
        }
    }

    public function detach(Observer $observer) {
        if (!empty($this->observers)) {
            $i = array_search($observer, $this->observers);
            if ($i !== false) {
                unset($this->observers[$i]);
            }
        }
    }

    public function getState() {
        return $this->state;
    }

    public function setState($state) {
        $this->state = $state;
        $this->notify();
    }

    public function notify() {
        if (!empty($this->observers)) {
            foreach ($this->observers as $observer) {
                $observer->update($this);
            }
        }
    }


    public function getObservers() {
        return $this->observers;
    }
}
Copier après la connexion

La méthode souscrit l'observateur à un sujet afin que tout changement d'état puisse lui être communiqué. La méthode attach() désabonne l'observateur du sujet afin qu'il n'observe plus les changements d'état du sujet. La méthode detach() définit l'état actuel du sujet et les appels setState() pour mettre à jour l'observateur, c'est-à-dire pour publier une notification à chaque observateur. Les méthodes notify() mettent à jour chaque objet souscrit en itérant via la liste interne et en appelant à leur tour la méthode notify() de chaque membre. Les méthodes update() et getState() ne sont que des fonctions d'assistance qui renvoient l'état du sujet actuel et de la liste des observateurs. getObservers()

Ajouter soigneusement ... intégrer ensemble

Maintenant, avec la classe de base abstraite pour les observateurs et les sujets, j'ai pu intégrer le logiciel Forum dans mon portail Web existant. J'ai besoin de définir la classe AUTH du portail comme un sujet observable et de définir son état observable lorsque l'utilisateur se connecte ou se déconnecte du portail.

<?php
class Auth extends Subject
{
    function login() {
        // 执行登录身份验证的现有代码
        // ...

        // 向任何观察者发出信号,表明用户已登录
        $this->setState("login");
    }

    function logout() {
        // 执行用户注销时执行某些操作的现有代码
        // 例如销毁会话等...

        // 向任何观察者发出信号,表明用户已注销
        $this->setState("logout");
    }
}
Copier après la connexion
J'ai prolongé la classe de sujet afin que l'auth puisse être observable, puis j'ai ajouté un appel à

dans les méthodes login() et logout(). Pour sous-classer l'observateur, j'ai créé une classe AUTH_FORUMHOOK qui est responsable de l'appel des fonctions de connexion et de déconnexion de l'API du forum. setState()

<?php
class Auth_ForumHook extends Observer
{
    function login($subject) {
        // 调用论坛的 API 函数以登录用户
        // ...
    }

    function logout($subject) {
        // 调用论坛的 API 函数以注销用户
        // ...
    }
}
Copier après la connexion
D'autres dans la base de code, où la classe AUTH dans le portail est instanciée, j'attache l'instance Auth_ForumHook afin que l'observateur soit informé de tout changement d'état dans l'authentification.

<?php
abstract class Observer
{
    public function __construct($subject = null) {
        if (is_object($subject) && $subject instanceof Subject) {
            $subject->attach($this);
        }
    }

    public function update($subject) {
        // 查找具有状态名称的观察者方法
        if (method_exists($this, $subject->getState())) {
            call_user_func_array(array($this, $subject->getState()), array($subject));
        }
    }
}
Copier après la connexion
Copier après la connexion

Ce sont tous mes besoins de codage supplémentaires en plus de préparer des classes Résumé et des classes de matières. Tout changement d'état déclenché par les méthodes login() et logout() d'Auth> informeront l'observateur auth_forumhook et se connectera automatiquement ou se déconnecter de l'utilisateur dans le forum. Pour ajouter un nouvel observateur, par exemple, pour se connecter au tracker pour enregistrer lorsqu'un utilisateur se connecte ou se connecte du portail, fournissez simplement une classe d'observateurs spécifique et attachez-la à la rubrique Auth sans modifier davantage les méthodes login() et logout() de l'objet AUTH existant.

Résumé

Si vous avez plusieurs objets qui dépendent d'un autre objet et que vous devez effectuer des opérations lorsque l'état de cet objet change, ou un objet doit informer d'autres objets sans savoir qui ou combien ils sont, alors le modèle d'observateur est un modèle de conception approprié et applicable. Dans cet article, je vous montre le modèle de base-observateur de sujets et fournit des exemples concrètes de la façon d'étendre facilement les fonctionnalités d'une classe existante en utilisant ce modèle sans couplage étroitement de nouvelles exigences. Ce modèle vous permet d'atteindre un niveau de cohérence plus élevé entre les objets liés et dépendants sans sacrifier la réutilisabilité de votre code.

Images de JPF / Shutterstock

(La section FAQ suivante a été omise en raison de la durée de l'article. Le contenu central a été réorganisé et poli sur elle.)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal