zoukankan      html  css  js  c++  java
  • 「PHP」观察者模式模式

    引言
     
      所属:行为型模式,常用设计模式之一
     
        学习资料:
    • 《大话设计模式》程杰
    模式概述
     
      观察者模式定义了一种一对多的依赖关系,让多个观察者对象监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使他们能够自动更新自己
     
      应用场景:当一个对象的改变需要同事改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
      观察者模式所作的工作其实就是在接触耦合。让耦合的双方都依赖于抽象类,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化
     
    举个栗子
     
        一家公司,用户A喜欢玩游戏,用户B喜欢看股票,上班不好好工作,经常被老板抓到,然后两人想了一个方案:贿赂前台妹子,当老板到前台的时候嘱咐前台妹子通知一下,也好不被抓到,那么程序如何设计呢。
           
     
        流程图如下:
          
              
      
    程序设计代码:
    1. 抽象观察者,具体观察者
    <?php
    /**
     * 抽象观察者
     */
    namespace observer_factory;
    
    abstract class ObserverAbstract
    {
        public abstract function update($news);
    }
    <?php
    
    /**
     * 正在玩的员工
     */
    namespace observer_factory;
    
    class NbaObserver extends ObserverAbstract
    {
        protected $name;
    
        protected $secretary;
    
        public function __construct(string $name, SubjectInterface $secretary)
        {
            $this->name = $name;
    
            $this->secretary = $secretary;
        }
    
        /**
         * 收到通知后的具体操作
         * @param $news
         */
        public function update($news)
        {
            echo $this->name.$news.'不要在玩了,继续工作!';
        }
    }
    <?php
    /**
     * 正在炒股的用户
     */
    namespace observer_factory;
    
    class StockObserver extends ObserverAbstract
    {
        protected $name;
    
        protected $secretary;
    
        public function __construct(string $name, SubjectInterface $secretary)
        {
            $this->name = $name;
    
            $this->secretary = $secretary;
        }
        /**
         * 收到通知后的具体操作
         * @param $news
         */
        public function update($news)
        {
            echo $this->name.$news.'不要在看股票,继续工作!';
        }
    }

    2. 抽象通知者,具体通知者

    <?php
    /**
     * 抽象通知者
     */
    namespace observer_factory;
    
    interface SubjectInterface
    {
        /**
         * 增加同事
         * @param ObserverAbstract $observer 针对抽象变成,减少了与具体类的耦合,也就是只有在继承抽象观察者的具体观察者才可以使用
         */
        public function attach($key, ObserverAbstract $observer);
    
        /**
         * 删除同事
         * @param ObserverAbstract $observer 针对抽象变成,减少了与具体类的耦合,也就是只有在继承抽象观察者的具体观察者才可以使用
         */
        public function detach($key);
    
        /**
         * 发送消息
         */
        public function notify();
    
        /**
         * @param $news
         */
        public function secretaryNews($news);
    }
    <?php
    /**
     * 通知者A
     */
    namespace observer_factory;
    
    class SubjectA implements SubjectInterface
    {
        /**
         * 同事列表
         */
        private $list = [];
    
        private $news;
    
        /**
         * 增加同事
         * @param ObserverAbstract $observer 针对抽象变成,减少了与具体类的耦合,也就是只有在继承抽象观察者的具体观察者才可以使用
         */
        public function attach($key, ObserverAbstract $observer)
        {
            $this->list[$key] = $observer;
        }
    
        /**
         * 删除同事
         * @param ObserverAbstract $observer 针对抽象变成,减少了与具体类的耦合,也就是只有在继承抽象观察者的具体观察者才可以使用
         */
        public function detach($key)
        {
            unset($this->list[$key]);
        }
    
        /**
         * 发送消息
         */
        public function notify()
        {
            foreach ($this->list AS $val) {
                $val->update($this->news);
            }
        }
    
        /**
         * @param $news
         */
        public function secretaryNews($news)
        {
            $this->news = $news;
        }
    }
    <?php
    
    namespace observer_factory;
    
    class SubjectB implements SubjectInterface
    {
        /**
         * 同事列表
         */
        private $list = [];
    
        private $news;
    
        /**
         * 增加同事
         * @param ObserverAbstract $observer 针对抽象变成,减少了与具体类的耦合,也就是只有在继承抽象观察者的具体观察者才可以使用
         */
        public function attach($key, ObserverAbstract $observer)
        {
            $this->list[$key] = $observer;
        }
    
        /**
         * 删除同事
         * @param ObserverAbstract $observer 针对抽象变成,减少了与具体类的耦合,也就是只有在继承抽象观察者的具体观察者才可以使用
         */
        public function detach($key)
        {
            unset($this->list[$key]);
        }
    
        /**
         * 发送消息
         */
        public function notify()
        {
            foreach ($this->list AS $val) {
                $val->update($this->news);
            }
        }
    
        /**
         * @param $news
         */
        public function secretaryNews($news)
        {
            $this->news = $news;
        }
    }

    3. 测试

    <?php
    
    namespace observer_factory;
    
    include '../autoload.php';
    
    // 通知者A 进行通知
    $tongzhizhe = new SubjectA();
    $tongshi1 = new NbaObserver('用户A', $tongzhizhe);
    $tongshi2 = new StockObserver('用户B', $tongzhizhe);
    
    $tongzhizhe->attach('用户A', $tongshi1);
    $tongzhizhe->attach('用户B', $tongshi2);
    
    $tongzhizhe->secretaryNews('老板回来了');
    $tongzhizhe->notify();
     
    以下为源码地址

      

      GitHub源码地址:https://github.com/xiaobaoword/design_pattern/tree/master

  • 相关阅读:
    Linux关机命令详解
    这二个月都在失眠中。
    GMAIL绑定自己的域名MX解析出现错误
    又上火了。
    FTP命令
    怎样做反向域名解析?
    linux 一些常用到的命令。
    LINUX怎么换IP。
    关于 MOD 和 \ 选择
    WIN2000和WIN2003连备份机的疑问
  • 原文地址:https://www.cnblogs.com/houdabao/p/9567331.html
Copyright © 2011-2022 走看看