简介

也叫做公布/订阅模式,多个观察者可订阅一个主题对象,当主题状态发生变化时会告诉所有已订阅的观察者,观察者可自在解决。

角色

  • Subject/Publisher 主题/发布者

    保护已订阅的观察者

    告诉已订阅的观察者

  • 形象Subscribe 订阅者

    定义订阅者接口

  • 具体Subscribe 订阅者

    实现订阅者通用接口,并实现各自逻辑

类图

代码

class Subject implements \SplSubject{    public $state;    private $observers;    public function __construct()    {        $this->observers = new \SplObjectStorage();    }    public function attach(\SplObserver $observer): void    {        echo "Subject: Attached an observer.\n";        $this->observers->attach($observer);    }    public function detach(\SplObserver $observer): void    {        $this->observers->detach($observer);        echo "Subject: Detached an observer.\n";    }    public function notify(): void    {        echo "Subject: Notifying observers...\n";        foreach ($this->observers as $observer) {            $observer->update($this);        }    }    public function someBusinessLogic(): void    {        echo "\nSubject: I'm doing something important.\n";        $this->state = rand(0, 10);        echo "Subject: My state has just changed to: {$this->state}\n";        $this->notify();    }}class ConcreteObserverA implements \SplObserver{    public function update(\SplSubject $subject): void    {        if ($subject->state < 3) {            echo "ConcreteObserverA: Reacted to the event.\n";        }    }}class ConcreteObserverB implements \SplObserver{    public function update(\SplSubject $subject): void    {        if ($subject->state == 0 || $subject->state >= 2) {            echo "ConcreteObserverB: Reacted to the event.\n";        }    }}$subject = new Subject();$o1 = new ConcreteObserverA();$subject->attach($o1);$o2 = new ConcreteObserverB();$subject->attach($o2);$subject->someBusinessLogic();$subject->someBusinessLogic();$subject->detach($o2);$subject->someBusinessLogic();

output:

Subject: Attached an observer.Subject: Attached an observer.Subject: I'm doing something important.Subject: My state has just changed to: 2Subject: Notifying observers...ConcreteObserverA: Reacted to the event.ConcreteObserverB: Reacted to the event.Subject: I'm doing something important.Subject: My state has just changed to: 0Subject: Notifying observers...ConcreteObserverA: Reacted to the event.ConcreteObserverB: Reacted to the event.Subject: Detached an observer.Subject: I'm doing something important.Subject: My state has just changed to: 8Subject: Notifying observers...

本文由mdnice多平台公布