共计 2539 个字符,预计需要花费 7 分钟才能阅读完成。
应用场景
假如项目经理让咱们写了一个登陆接口,咔咔擦擦写完了
- 第二天让咱们退出统计登陆次数,而后在前面加代码
- 第三天让咱们判断登陆地区,又在前面加代码
- 第四天让咱们在用户登陆后推送流动,再再前面加代码
- 第 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();
正文完