• 深入 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收到了通知,内容为:开启
    
  • 相关阅读:
    "点赞"组件:<like> —— 快应用组件库H-UI
    "视频新闻"组件:<news-video> —— 快应用组件库H-UI
    "热点话题"组件:<news-hot> —— 快应用组件库H-UI
    "图集新闻"组件:<news-image> —— 快应用组件库H-UI
    "新闻详情"组件:<news-detail> —— 快应用组件库H-UI
    "新闻三叶草"组件:<news-three-pics> —— 快应用组件库H-UI
    "新闻单叶草"组件:<news> —— 快应用组件库H-UI
    adjustResize模式下ExpandaleListView中输入框焦点错乱及布局底部的导航栏被顶在键盘上方的处理
    recyclerview嵌套GridView去屏蔽后者的点击事件,而是前者响应到事件。
    安卓编程之自定义字体控件导致应用闪退
  • 原文地址:https://www.cnblogs.com/danhuang/p/13183073.html
Copyright © 2020-2023  润新知