解析PHP观察者模式Observer

吾爱主题 阅读:150 2021-11-15 15:58:00 评论:0
目录
  • 观察者模式结构图
  • 概念
  • 代码示例

观察者模式结构图

概念

一个"演员"(被观察者),一群"观众"(观察者),一台"摄影机"(记录容器)

【观察者模式中主要角色】

1.抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有任意多个观察者。 抽象主题提供了增加和删除观察者对象的接口。

2.抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。

3.具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。

4.具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致。

【使用场景】

假设项目经理让我们写了一个登陆接口,咔咔擦擦写完了

第二天让我们加入统计登陆次数,然后在后面加代码第三天让我们判断登陆地区,又在后面加代码第四天让我们在用户登陆后推送活动,再再后面加代码第N天,这个接口已经杂乱到没人想维护了

我们需要让项目保持高内聚低耦合,就可以用到观察者模式(非必须,看需求)

【观察者模式与其它模式】

1.【中介者模式】(Mediator):通过封装复杂的更新语义,ChangeManager充当目标和观察者之间的中介者。
2.【单例模式】(singleton模式):ChangeManager可使用Singleton模式来保证它是唯一的并且是可全局访问的。

代码示例

接口示例

?
1 2 3 4 5 6 7 8 9 // 主题接口 interface Subject{      public function register(Observer $observer );      public function notify(); } // 观察者接口 interface Observer{      public function watch(); }

Subject就是被观察者,Observer就是观众,也就是观察者

被观察者

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 // 被观察者 class Action implements Subject{       public $_observers = array ();       public function register(Observer $observer ){           $this ->_observers[]= $observer ;       }         public function notify(){           foreach ( $this ->_observers as $observer ) {               $observer ->watch();           }         }   }

Action实现了被观察者接口,他现在就是被观察者,再定义一个$_observers数组,他就是记录观众的容器了。

首先实现register方法,用它传入一个观察者,然后塞到数组里,再实现notify()方法,它会遍历容器数组,执行每个观察者的watch()方法。

观察者

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 观察者 class Cat implements Observer{       public function watch(){           echo "Cat watches TV<hr/>" ;       }   }   class Dog implements Observer{       public function watch(){           echo "Dog watches TV<hr/>" ;       }   }   class People implements Observer{       public function watch(){           echo "People watches TV<hr/>" ;       }   }

这里定义了三个观察者,全都实现了Observer接口,前面的Subject会循环调用每个观察者的watch()方法,所以我们需要实现每个观察者的watch()方法。

调用

?
1 2 3 4 5 6 // 应用实例 $action = new Action(); $action ->register( new Cat()); $action ->register( new People()); $action ->register( new Dog()); $action ->notify();

首先new被观察者对象,执行它的register()方法,把每个观察者都放入容器数组,最后执行notify()方法,通知所有观察者执行自己的方法。

PHP原生自带的观察者模式

PHP有自带的观察者模式

  • splsubject接口 - 被观察者
  • Observer接口 - 观察者
  • SplObjectStorage对象 - 容器

首先我们有一个用户登录类

?
1 2 3 4 5 6 class user{      public function login()    {        echo '登录完毕'    }

让他实现splsubject接口成为被观察者。

  • 首先在构造函数里,让他new SplObjectStorag()对象并赋值到属性上方便后面调用
  • 实现attach()方法,用来注册观察者
  • 实现detach()方法,用来删除观察者
  • 实现notify()方法,用来遍历容器,调用每个观察者的update方法(必须是update)
  • rewind方法是容器指针重置到最开始,valid方法检测容器是否遍历完成并返回布尔,current方法是获取当前的观察者,next方法是将指针后移一位
  • 修改login()方法,在里面调用notify()来通知观察者事件完成了
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class user implements splsubject{        protected $observer = null;        public function __construct()      {          $this ->observer = new SplObjectStorage();      }        public function login()      {          $this ->notify();          echo '登录完毕' ;      }        public function attach(SplObserver $observer )      {          $this ->observer->attach( $observer );      }        public function detach(SplObserver $observer )      {          $this ->observer->detach( $observer );      }        public function notify()      {          $this ->observer-> rewind ();          while ( $this ->observer->valid())          {              $observer = $this ->observer->current();              $observer ->update( $this );              $this ->observer->next();          }      } }

观察者

每个观察者实现SplObserver接口,并实现update()方法

?
1 2 3 4 5 6 7 8 9 10 11 12 13 class cat implements SplObserver {        public function update(SplSubject $subject )      {          echo '小猫叫一下' ;      } } class dog implements SplObserver {      public function update(SplSubject $subject )      {          echo '小狗吼一声' ;      } }

应用

?
1 2 3 4 5 // 实时观察 $user = new user(); $user ->attach( new cat()); $user ->attach( new dog()); $user ->login();

以上就是解析PHP观察者模式(Observer)的详细内容,更多关于PHP观察者模式(Observer)的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/phpyu/p/13526403.html

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容