码迷,mamicode.com
首页 > 其他好文 > 详细

深入 Laravel 内核之观察者模式

时间:2020-06-23 17:06:41      阅读:50      评论:0      收藏:0      [点我收藏+]

标签:client   viewer   对象   模式   业务逻辑   attach   upd   vat   业务   

装饰模式核心内容:

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

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

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

    public function attach(Observer $observer)
    {
        echo __CLASS__ . "绑定观察者:" . $observer->getClassName() . "\n\r";
        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() . "\n\r";
            $viewer->update($this);
        }
    }
}

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

class ConcreteSubject extends Subject
{
    public function setState($state)
    {
        echo __CLASS__ . "修改状态并调用 notify 方法\n\r";
        $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 . "\n\r";
    }

    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 . "\n\r";
    }

    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 内核之观察者模式

标签:client   viewer   对象   模式   业务逻辑   attach   upd   vat   业务   

原文地址:https://www.cnblogs.com/danhuang/p/13183073.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!