加入收藏 | 设为首页 | 会员中心 | 我要投稿 莱芜站长网 (https://www.0634zz.com/)- 云连接、建站、智能边缘云、设备管理、大数据!
当前位置: 首页 > 编程开发 > PHP > 正文

PHP设计模式中观察者模式讲解

发布时间:2023-02-16 12:42:02 所属栏目:PHP 来源:互联网
导读:本文实例讲述了PHP设计模式之观察者模式定义与用法。分享给大家供大家参考,观察者模式 当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新 适用场景 类似触发钩子事件,可做消息通知、框架底层监听。 一个对象的改变会导致一个或多个对象
  本文实例讲述了PHP设计模式之观察者模式定义与用法。分享给大家供大家参考,观察者模式 当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新
 
  适用场景
  类似触发钩子事件,可做消息通知、框架底层监听。
  一个对象的改变会导致一个或多个对象发生改变,方便扩展的写法。
 
  优点
  方便扩展,降低耦合,统一触发规则。当需要新增或者删除一个观察者的时候,只需要增加观察者就行。 
 
  缺点
  相比于不用观察者而是直接依赖某些类,增加代码的复杂度。
  如果观察者者被观察者互相依赖,有产生死循环的可能。
 
  补充
  需要理清楚观察者和被观察者是谁,观察者可以理解为被动受到通知的对象。被观察者是主动发送通知的对象。
  固定的套路,被观察者至少需要一个添加观察者的方法和一个通知观察者的方法用来确定身份和发送通知(一般有三个,多一个删除观察者的方法),观察者至少需要一个更新的方法用于接收被观察者的通知。

  //假设用户成功购买商品后需要发送邮件和短信通知
  class Order {
      private $observers = [];
      //添加观察者
      public function attach($type, $observer) {
          $this->observers[$type] = $observer;
      }
      //对每个观察者进行通知
      public function notify() {
          if ($this->observers == []) {
              return null;
          }
          foreach ($this->observers as $every_observer) {
              (new $every_observer)->update($this);
          }
      }
      //购买商品,触发通知
      public function buyGoods() {
          //todo 订单操作
          echo '商品购买完成' . PHP_EOL;
          $this->notify();
      }
  }
  class Mail {
      public function update($observer) {
          echo '发送电子邮件' . PHP_EOL;
      }
  }
  class Sms {
      public function update($observer) {
          echo '发送短信' . PHP_EOL;
      }
  }
  $order = new Order();
  //添加观察者
  $order->attach('mail', Mail::class);
  $order->attach('sms', Sms::class);
  $order->buyGoods();
  代码(基于SPL实现)
  SPL(Standard PHP Library)标准PHP类库,用于解决典型问题的一组接口与类的集合。
  class OrderListener implements SplSubject {
      //观察者列表
      public $observers;
      public function __construct() {
          //SplObjectStorage类提供从对象到数据的映射,或者通过忽略数据,提供对象集的映射。在许多需要唯一标识对象的情况下,这种双重用途非常有用。
          $this->observers = new SplObjectStorage();
      }
      //添加要通知的对象
      public function attach(SplObserver $observer) {
          $this->observers->attach($observer);
      }
      //移除要通知的对象
      public function detach(SplObserver $observer) {
          $this->observers->detach($observer);
      }
      //通知
      public function notify() {
          //将迭代器(此处可以理解为指针)倒回到第一个存储元素。
          $this->observers->rewind();
          //判断指针是否有效
          while($this->observers->valid()) {
              //获取当前的观察者
              $curr_obj = $this->observers->current();
              //对当前观察者进行通知
              $curr_obj->update($this);
              //向下移动指针
              $this->observers->next();
          }
      }
      //触发通知
      public function buyGoods() {
          echo '购买成功' . PHP_EOL;
          $this->notify();
      }
  }
  //SplObserver接口与SplSubject接口一起使用,以实现观察者设计模式。
  class Mail implements SplObserver {
      //对被观察的对象做相应的处理
      public function update(SplSubject $subject) {
          echo '发送邮件' . PHP_EOL;
      }
  }
  class Sms implements SplObserver {
      //对被观察的对象做相应的处理
      public function update(SplSubject $subject) {
          echo '发送短信' . PHP_EOL;
      }
  }
  $listener = new OrderListener();
  //添加观察者
  $listener->attach(new Mail());
  $listener->attach(new Sms());
  $listener->buyGoods();
  通知代码(基于SPL实现的notify方法优化)
  //以上代码的notify方法使用原生手动调整指针的方式去实现。也可以使用foreach去遍历实现
  public function notify() {
      foreach ($this->observers as $observer) {
          $observer->update($this);
      }
  }


(编辑:莱芜站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读