乐趣区

关于后端:行为型设计模式观察者发布订阅-Observer

简介

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

角色

  • 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...

本文由 mdnice 多平台公布

退出移动版