PHP面向对象深入理解之四(设计模式-观察者模式)

心已赠人 2022-06-09 06:19 253阅读 0赞

观察者模式对于PHP而言,有几个内置的接口实现,相关的模式,分别是 SplSubject

SubObserver 和 SplObjectStoarge,相比uml类图,我比较喜欢用更通俗易懂的关系图解释现象,如下图。

Center

被观察者 通过映射对象 存储了所有的 观察者对应的对象映射,然后在被观察者发生改变的时候,会循环映射对像,通知所有的观察者

,直接上代码。

主体(被观察者)类:

  1. /**
  2. * @package: 观察者模式
  3. * 所谓的观察者,通俗一点讲
  4. 主体 (被观察者 A) SplSubject
  5. 存储容器 (观察者映射表) SplObjectStorage
  6. 观察者 B1,B2,B3... SplObserver
  7. A一段发生改变,B1,B2,B3... 都会收到相应的通知
  8. */
  9. //------------主体 被观察者
  10. class Subject implements SplSubject
  11. {
  12. private $observers;
  13. private $data;
  14. public function setStorage()
  15. {
  16. $this->observers = new SplObjectStorage();
  17. }
  18. public function attach(SplObserver $observer)
  19. {
  20. $this->observers->attach($observer);
  21. }
  22. public function detach(SplObserver $observer)
  23. {
  24. $this->observers->detach($observer);
  25. }
  26. public function notify()
  27. {
  28. foreach($this->observers as $observer){
  29. $observer->update($this);
  30. }
  31. }
  32. public function setData($data)
  33. {
  34. $this->data = $data;
  35. }
  36. public function getData()
  37. {
  38. return $this->data;
  39. }
  40. }

观察者:

  1. //---------------观察者
  2. //---------也就是说 每一个观察者 只要实现 SplObserver 并实现方法update 就能被通知到
  3. class Observer implements SplObserver
  4. {
  5. private $name = '';
  6. public function __construct($name)
  7. {
  8. $this->name = $name;
  9. }
  10. public function update(SplSubject $subject)
  11. {
  12. echo $this->name.":";
  13. var_dump($subject->getData());
  14. }
  15. }

调用:

  1. // 实例使用
  2. $A = new Subject();
  3. $A->setStorage();
  4. $B1 = new Observer('B1');
  5. $B2 = new Observer('B2');
  6. $B3 = new Observer('B3');
  7. $A->attach($B1);
  8. $A->attach($B2);
  9. $A->attach($B3);
  10. $A->setData('123');
  11. $A->notify();
  12. $A->detach($B2);
  13. $A->setData('456');
  14. $A->notify();

调用结果:

B1:string(3) “123”
B2:string(3) “123”
B3:string(3) “123”
B1:string(3) “456”
B3:string(3) “456”

可以看到每个存在于映射对象里的对象都收到了相应的通知。其实具体的思路,我们不应该仅仅局限于

php所给的SplObjectStorage 存储,我们可以扩展到redis 及其他,SplSubject 和 SplObserver 也是,只要

实现 被观察者 能获取每一个观察者,并能调用相应的观察者通知方法,有点类似消息队列的定时推送,

发表评论

表情:
评论列表 (有 0 条评论,253人围观)

还没有评论,来说两句吧...

相关阅读