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 :
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('XXX','XXX','127.0.0.1'); ?> 出错时的运行结果: 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!