Maison  >  Article  >  développement back-end  >  Modèles de conception avancés orientés objet PHP : exemples d'utilisation de modèles d'observateur

Modèles de conception avancés orientés objet PHP : exemples d'utilisation de modèles d'observateur

巴扎黑
巴扎黑original
2017-05-23 13:45:561520parcourir

Qu'est-ce que le modèle d'observateur ?

Le modèle de conception d'observateur facilite la création d'objets qui visualisent l'état des objets cibles et fournit des fonctionnalités spécifiées qui sont découplées des objets principaux.

Le schéma est très simple : un objet se rend observable en ajoutant une méthode qui permet à un autre objet, un observateur, de s'enregistrer. Lorsqu'un objet observable change, il envoie des messages aux observateurs enregistrés. Ces observateurs utilisent ces informations pour effectuer des opérations indépendantes de l'objet observable. Le résultat est que les objets peuvent communiquer entre eux sans avoir à comprendre pourquoi.


UML

Ce diagramme détaille une conception de classe utilisant le modèle de conception Observer :

Modèles de conception avancés orientés objet PHP : exemples dutilisation de modèles dobservateur

Ce qui suit est une description de l'image ci-dessus :

1.MyObject est un objet observable, qui contient un tableau protégé par un observateur nommé observers. La méthode publique addObserver() accepte une instance d'un observateur et la stocke dans le tableau d'observateurs.

La méthode publique 2.doSomething() sera appelée. Cette méthode applique les changements d'état à MyObject. Par la suite, la méthode publique notify() sera appelée, qui peut parcourir le tableau d'observateurs de boucle.

3.MyObjectObserver a une méthode publique nommée change(), qui accepte une instance de MyObject. Cet observateur particulier effectuera ensuite une action sur le contenu de MyObject. Lorsqu'un observateur spécifique est trouvé dans le tableau d'observateurs, la méthode notify() de MyObject appelle directement la méthode change().

Exemple d'utilisation :

<?php  
interface Observable{  
    function attach( Observer $observer );  
    function detach( Observer $observer );  
    function notify();  
}  
  
  
class login implements Observable{  
    const LOGIN_USER_UNKNOW = 1;  
    const LOGIN_WRONG_PASS = 2;  
    const LOGIN_ACCESS = 3;  
    private $status = array();  
    private $observers = array();  
  
    public function setStatus( $status, $user, $ip ) {  
        $this->status = array( $status, $user, $ip );  
    }  
    public function getStatus() {  
        return $this->status;  
    }  
    public function handleLogin( $user, $pass, $ip ) {  
        switch ( mt_rand( 1, 3 ) ) {  
        case 1:  
            $this->setStatus( self::LOGIN_USER_UNKNOW, $user, $ip );  
            $ret = false;  
            break;  
        case 2:  
            $this->setStatus( self::LOGIN_WRONG_PASS, $user, $ip );  
            $ret = false;  
            break;  
        case 3:  
            $this->setStatus( self::LOGIN_ACCESS, $user, $ip );  
            $ret = true;  
            break;  
        }  
        $this->notify();  
        return $ret;  
    }  
  
  
    public function attach( Observer $observer ) {  
        $this->observers[] = $observer;  
    }  
  
    public function detach( Observer $observer ) {  
        $newObservers = array();  
        foreach ( $this->observers as $obs ) {  
            if ( $obs !== $observer )  
                $newObservers[] = $obs;  
        }  
        $this->observers = $newObservers;  
    }  
  
    public function notify() {  
        foreach ( $this->observers as $obs ) {  
            $obs->update( $this );  
        }  
    }  
}  
  
interface Observer{  
    function update( Observable $observable );  
}  
  
class SecurityMonitor implements Observer{  
    function update( Observable $observable ) {  
        $status = $observable->getStatus();  
        if($status[0] == Login::LOGIN_WRONG_PASS){  
            echo __CLASS__.":".$status[1]."于".$status[2]."登录失败";  
        }  
    }  
}  
  
$login = new Login();  
$login->attach(new SecurityMonitor());  
$login->handleLogin(&#39;XXX&#39;,&#39;XXX&#39;,&#39;127.0.0.1&#39;);  
?>  
出错时的运行结果:  
SecurityMonitor:XXX于127.0.0.1登录失败[Finished in 0.1s]

Vous pouvez voir dans le code que l'objet de connexion ajoute activement l'objet SecurityMonitor pour observation. De cette façon, pour appeler Login::getStatus(), la classe SecurityMonitor doit connaître plus d'informations. Bien que l'appel se produise sur un objet ObServable, rien ne garantit que l'objet soit également un objet Login. Pour résoudre ce problème, il existe un moyen : garder l'interface ObServable générique par intermittence, et la classe ObServer se charge de s'assurer que leurs corps sont du bon type. Ils peuvent même s'ajouter au sujet.

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:
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