应用场景

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

  • 第二天让咱们退出统计登陆次数,而后在前面加代码
  • 第三天让咱们判断登陆地区,又在前面加代码
  • 第四天让咱们在用户登陆后推送流动,再再前面加代码
  • 第N天,这个接口曾经芜杂到没人想保护了

咱们须要让我的项目放弃高内聚低耦合,就能够用到观察者模式(也不是非要,看需要)

概念

观察者,观察者,首先要有个被人察看的角色,这是惟一的,而后会有无数个观察者去看她,能够说是一群人在围观一个人,既然有无数个观众,那总得有个货色记录有哪些观察者,那就应该有一个相似于数组一样来贮存所有观察者,总结就是一个被观察者,无数个观察者,再有一个容器记录

代码示例

  • 接口示例
// 主题接口interface Subject{    public function register(Observer $observer);    public function notify();}// 观察者接口interface Observer{    public function watch();}

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

被观察者

// 被观察者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()办法。

观察者

// 观察者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()办法。
#### 调用

// 利用实例$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对象 - 容器

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

class user{  public function login()  {      echo '登录结束'  }

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

  • 首先在构造函数里,让他new SplObjectStorag()对象并赋值到属性上不便前面调用
  • 实现attach()办法,用来注册观察者
  • 实现detach()办法,用来删除观察者
  • 实现notify()办法,用来遍历容器,调用每个观察者的update办法(必须是update)
  • rewind办法是容器指针重置到最开始,valid办法检测容器是否遍历实现并返回布尔,current办法是获取以后的观察者,next办法是将指针后移一位
  • 批改login()办法,在外面调用notify()来告诉观察者事件实现了
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()办法

class cat implements SplObserver {    public function update(SplSubject $subject)    {        echo '小猫叫一下';    }}class dog implements SplObserver {    public function update(SplSubject $subject)    {        echo '小狗吼一声';    }}

利用

// 实时察看$user = new user();$user->attach(new cat());$user->attach(new dog());$user->login();