深入 Laravel 内核之观察者模式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入 Laravel 内核之观察者模式相关的知识,希望对你有一定的参考价值。

装饰模式核心内容:

  • 观察者模式又称为发布订阅模式,定义了对象间的一对多依赖关系,当一个对象状态发生改变时,其相关依赖的其他对象都能接收到通知;
  • 观察者模式的核心在于目标(Subject)和观察者(Observer)接口,目标有一个状态属性,观察者“订阅”这个目标,当目标的状态属性发生改变时,通知所有观察者。
  • 目标状态改变只需核心业务逻辑并调用通知接口,无需关心具体的观察者及其数量,降低对象之间的耦合度;

定义一个目标抽象类,提供绑定&解绑观察者的接口供客户端使用,提供通知观察者的接口供目标实现类使用:

abstract class Subject
{
    protected $stateNow;
    protected $observers = [];

    public function attach(Observer $observer)
    {
        echo __CLASS__ . "绑定观察者:" . $observer->getClassName() . "

";
        array_push($this->observers, $observer);
    }

    public function detach(Observer $observer)
    {
        $pos = 0;
        foreach ($this->observers as $viewer) {
            if ($viewer == $observer) {
                array_splice($this->observers, $pos, 1);
            }
            $pos++;
        }
    }

    public function notify()
    {
        foreach ($this->observers as $viewer) {
            echo __CLASS__ . "通知观察者:" . $viewer->getClassName() . "

";
            $viewer->update($this);
        }
    }
}

定义一个目标实现类,实现状态的变更业务:

class ConcreteSubject extends Subject
{
    public function setState($state)
    {
        echo __CLASS__ . "修改状态并调用 notify 方法

";
        $this->stateNow = $state;
        $this->notify();
    }

    public function getState()
    {
        return $this->stateNow;
    }
}

定义一个观察者抽象类,规范接收通知的接口:

abstract class Observer
{
    abstract public function update(Subject $subject);

    abstract public function getClassName();
}

定义两个观察者实现类,实现接收通知的业务逻辑:

class ConcreteObserverEmail extends Observer
{
    //维护一个指向具体目标对象的引用
    private $currentState;

    public function update(Subject $subject)
    {
        $this->currentState = $subject->getState();
        echo $this->getClassName() . "收到了通知,内容为:" . $this->currentState . "

";
    }

    public function getClassName() {
        return __CLASS__;
    }
}

class ConcreteObserverPhone extends Observer
{
    //维护一个指向具体目标对象的引用
    private $currentState;

    public function update(Subject $subject)
    {
        $this->currentState = $subject->getState();
        echo $this->getClassName() . "收到了通知,内容为:" . $this->currentState . "

";
    }

    public function getClassName() {
        return __CLASS__;
    }
}

定义一个客户端,给目标绑定观察者,查看效果:

class Client
{
    public function main()
    {
        $sub = new ConcreteSubject();
        $obEmail = new ConcreteObserverEmail();
        $obPhone = new ConcreteObserverPhone();

        $sub->attach($obEmail);
        $sub->attach($obPhone);
        $sub->setState(‘开启‘);
    }
}

(new Client())->main();

输出结果:

Subject绑定观察者:ConcreteObserverEmail
Subject绑定观察者:ConcreteObserverPhone
ConcreteSubject修改状态并调用 notify 方法
Subject通知观察者:ConcreteObserverEmail
ConcreteObserverEmail收到了通知,内容为:开启
Subject通知观察者:ConcreteObserverPhone
ConcreteObserverPhone收到了通知,内容为:开启

以上是关于深入 Laravel 内核之观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

yii2深入理解之内核解析

深入理解JavaScript系列(32):设计模式之观察者模式

深入理解JavaScript系列(32):设计模式之观察者模式

深入浅出设计模式之策略模式观察者模式

设计模式之单例模式

Spring Ioc源码深入剖析预备知识