Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Beobachtermuster

PHP-Beobachtermuster

高洛峰
高洛峰Original
2016-11-21 17:01:061640Durchsuche

Konzept

Das Beobachtermuster ist ein Verhaltensmuster, das eine Eins-zu-Viele-Abhängigkeitsbeziehung zwischen Objekten definiert, sodass alle davon abhängigen Objekte benachrichtigt und aktualisiert werden, wenn sich der Zustand eines Objekts ändert automatisch.

Wenn sich der Zustand eines Objekts ändert, wirkt sich dies auf die Änderungen mehrerer anderer Objekte aus. Zu diesem Zeitpunkt kann der Beobachtermodus verwendet werden.

Das Beobachtermuster entspricht dem Schnittstellenisolationsprinzip und erreicht eine lose Kopplung zwischen Objekten.

Alias

Publish-Subscribe Pattern

Model-View Pattern

Source-Listener Pattern 🎜>Slave-Muster

Rolle

Abstraktes Subjekt (Subjekt): Es speichert die Referenzen aller Beobachterobjekte in einer Sammlung, jedes Subjekt kann eine beliebige Anzahl von Beobachtern haben. Das abstrakte Thema bietet eine Schnittstelle zum Hinzufügen und Entfernen von Beobachterobjekten.

Konkretes Subjekt (ConcreteSubject): Speichern Sie den relevanten Status in einem bestimmten Beobachterobjekt. Wenn sich der interne Status des spezifischen Subjekts ändert, wird eine Benachrichtigung an alle registrierten Beobachter gesendet.

Abstrakter Beobachter (Beobachter): Definieren Sie eine Schnittstelle für alle konkreten Beobachter und aktualisieren Sie sich selbst, wenn sie vom Thema benachrichtigt werden.

Konkreter Beobachter: Implementiert die Aktualisierungsschnittstelle, die für die abstrakte Beobachterrolle erforderlich ist, um ihren eigenen Status mit dem Subjektstatus zu koordinieren.

UML-Diagramm

PHP-BeobachtermusterCode

Beispielcode

Die SplSubject- und SqlOberver-Schnittstellen wurden in PHP SPL bereitgestellt, Quellcode Wie folgt:

Nachfolgend schreiben wir unseren eigenen Code basierend auf diesen beiden Spl-Schnittstellen:
/**
 * The <b>SplSubject</b> interface is used alongside
 * <b>SplObserver</b> to implement the Observer Design Pattern.
 * @link http://php.net/manual/en/class.splsubject.php
 */
interface SplSubject  {

        /**
         * Attach an SplObserver
         * @link http://php.net/manual/en/splsubject.attach.php
         * @param SplObserver $observer <p>
     * The <b>SplObserver</b> to attach.
         * </p>
         * @return void 
         * @since 5.1.0
         */
        public function attach (SplObserver $observer);

        /**
         * Detach an observer
         * @link http://php.net/manual/en/splsubject.detach.php
         * @param SplObserver $observer <p>
     * The <b>SplObserver</b> to detach.
         * </p>
         * @return void 
         * @since 5.1.0
         */
        public function detach (SplObserver $observer);

        /**
         * Notify an observer
         * @link http://php.net/manual/en/splsubject.notify.php
         * @return void 
         * @since 5.1.0
         */
        public function notify ();

}

/**
 * The <b>SplObserver</b> interface is used alongside
 * <b>SplSubject</b> to implement the Observer Design Pattern.
 * @link http://php.net/manual/en/class.splobserver.php
 */
interface SplObserver  {

        /**
         * Receive update from subject
         * @link http://php.net/manual/en/splobserver.update.php
         * @param SplSubject $subject <p>
     * The <b>SplSubject</b> notifying the observer of an update.
         * </p>
         * @return void 
         * @since 5.1.0
         */
        public function update (SplSubject $subject);

}

Laufende Ergebnisse
<?php
header(&#39;Content-type:text/html;charset=utf-8&#39;);

/**
 * Class Subject 主题
 */
class Subject implements SplSubject
{
    private $_observers = [];

    /**
     * 实现添加观察者方法
     *
     * @param SplObserver $observer
     */
    public function attach(SplObserver $observer)
    {
        if (!in_array($observer, $this->_observers)) {
            $this->_observers[] = $observer;
        }
    }

    /**
     * 实现移除观察者方法
     *
     * @param SplObserver $observer
     */
    public function detach(SplObserver $observer)
    {
        if (false !== ($index = array_search($observer, $this->_observers))) {
            unset($this->_observers[$index]);
        }
    }

    /**
     * 实现提示信息方法
     */
    public function notify()
    {
        foreach ($this->_observers as $observer) {
            $observer->update($this);
        }
    }

    /**
     * 设置数量
     *
     * @param $count
     */
    public function setCount($count)
    {
        echo "数据量加" . $count . &#39;<br>&#39;;
    }

    /**
     * 设置积分
     *
     * @param $integral
     */
    public function setIntegral($integral)
    {
        echo "积分量加" . $integral . &#39;<br>&#39;;
    }

}

/**
 * Class Observer1 观察者一
 */
class Observer1 implements SplObserver
{
    public function update(SplSubject $subject)
    {
        $subject->setCount(10);
    }
}

/**
 * Class Observer2 观察者二
 */
class Observer2 implements SplObserver
{
    public function update(SplSubject $subject)
    {
        $subject->setIntegral(10);
    }
}


/**
 * Class Client 客户端
 */
class Client
{
    /**
     * 测试方法
     */
    public static function test()
    {
        // 初始化主题
        $subject = new Subject();
        // 初始化观察者一
        $observer1 = new Observer1();
        // 初始化观察者二
        $observer2 = new Observer2();
        // 添加观察者一
        $subject->attach($observer1);
        // 添加观察者二
        $subject->attach($observer2);
        // 消息提示
        $subject->notify();//输出:数据量加1 积分量加10
        // 移除观察者一
        $subject->detach($observer1);
        // 消息提示
        $subject->notify();//输出:数据量加1 积分量加10 积分量加10
    }
}

// 执行测试
Client::test();

Fügen Sie 10 Punkte zum Betrag hinzu von Daten

Menge plus 10

Ganzzahlige Menge plus 10


Vor- und Nachteile

Vorteile

Die Kopplung zwischen Beobachter und Subjekt ist gering ;

Unterstützt Broadcast-Kommunikation;

Nachteile

Da der Beobachter die Existenz anderer Beobachter nicht kennt, kennt er möglicherweise nicht die endgültigen Kosten für die Änderung des Ziels. Dies kann zu unerwarteten Updates führen.

Anwendbare Szenarien

Wenn ein abstraktes Modell zwei Aspekte hat, von denen einer vom anderen abhängt.

Wenn Änderungen an einem Objekt gleichzeitig Änderungen an anderen Objekten erfordern, ist nicht bekannt, wie viele Objekte geändert werden müssen.

Wenn ein Objekt andere Objekte benachrichtigen muss, kann es nicht davon ausgehen, wer die anderen Objekte sind. Mit anderen Worten: Sie möchten nicht, dass diese Objekte eng miteinander verbunden sind.

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