Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-objektorientierte erweiterte Entwurfsmuster: Beispiele für die Verwendung von Observer-Mustern

PHP-objektorientierte erweiterte Entwurfsmuster: Beispiele für die Verwendung von Observer-Mustern

巴扎黑
巴扎黑Original
2017-05-23 13:45:561577Durchsuche

Was ist das Beobachtermuster?

Das Beobachter-Entwurfsmuster erleichtert die Erstellung von Objekten, die den Status von Zielobjekten anzeigen, und bietet spezifizierte Funktionen, die von Kernobjekten entkoppelt sind.

Das Muster ist sehr einfach: Ein Objekt macht sich selbst beobachtbar, indem es eine Methode hinzufügt, die es einem anderen Objekt, einem Beobachter, ermöglicht, sich selbst zu registrieren. Wenn sich ein beobachtbares Objekt ändert, sendet es Nachrichten an registrierte Beobachter. Diese Beobachter nutzen diese Informationen, um Operationen unabhängig vom beobachtbaren Objekt durchzuführen. Das Ergebnis ist, dass Objekte miteinander kommunizieren können, ohne verstehen zu müssen, warum.


UML

Dieses Diagramm beschreibt detailliert einen Klassenentwurf unter Verwendung des Observer-Entwurfsmusters:

PHP-objektorientierte erweiterte Entwurfsmuster: Beispiele für die Verwendung von Observer-Mustern

Das Folgende ist eine Beschreibung des obigen Bildes:

1.MyObject ist ein beobachtbares Objekt, das ein beobachtergeschütztes Array mit dem Namen Observer enthält. Die öffentliche Methode addObserver() akzeptiert eine Instanz eines Beobachters und speichert sie im Beobachter-Array.

Die öffentliche Methode 2.doSomething() wird aufgerufen. Diese Methode wendet Zustandsänderungen auf MyObject an. Anschließend wird die öffentliche Methode notify() aufgerufen, die das Schleifenbeobachter-Array durchlaufen kann.

3.MyObjectObserver verfügt über eine öffentliche Methode namens change(), die eine Instanz von MyObject akzeptiert. Dieser bestimmte Beobachter führt dann eine Aktion mit dem Inhalt von MyObject durch. Wenn ein bestimmter Beobachter im Beobachter-Array gefunden wird, ruft die notify()-Methode von MyObject direkt die change()-Methode auf.

Verwendungsbeispiel:

<?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]

Sie können im Code sehen, dass das Login-Objekt das SecurityMonitor-Objekt aktiv zur Beobachtung hinzufügt. Um Login::getStatus() aufzurufen, muss die SecurityMonitor-Klasse auf diese Weise weitere Informationen kennen. Obwohl der Aufruf für ein ObServable-Objekt erfolgt, gibt es keine Garantie dafür, dass das Objekt auch ein Login-Objekt ist. Um dieses Problem zu lösen, gibt es einen Weg: Halten Sie die ObServable-Schnittstelle zeitweise generisch, und die ObServer-Klasse ist dafür verantwortlich, sicherzustellen, dass ihre Körper den richtigen Typ haben. Sie können sich sogar selbst zum Thema hinzufügen.

Das obige ist der detaillierte Inhalt vonPHP-objektorientierte erweiterte Entwurfsmuster: Beispiele für die Verwendung von Observer-Mustern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn