简介
也叫做发布/订阅模式,多个观察者可订阅一个主题对象,当主题状态发生变化时会通知所有已订阅的观察者,观察者可自由处理。
角色
-
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: 2
Subject: 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: 0
Subject: 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: 8
Subject: Notifying observers...
Top comments (0)