学习php设计模式 php实现观察者模式(Observer)


Posted in PHP onDecember 09, 2015

一、意图
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新【GOF95】
又称为发布-订阅(Publish-Subscribe)模式、模型-视图(Model-View)模式、源-监听(Source-Listener)模式、或从属者(Dependents)模式
二、观察者模式结构图

学习php设计模式 php实现观察者模式(Observer) 

三、观察者模式中主要角色
抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有任意多个观察者。抽象主题提供了增加和删除观察者对象的接口。
抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。
具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。
具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致。
四、观察者模式的优点和缺点
观察者模式的优点:
1、观察者和主题之间的耦合度较小;
2、支持广播通信;
观察者模式的缺点:
1、由于观察者并不知道其它观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。
五、观察者模式适用场景
1、当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。
2、当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。
3、当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。
六、观察者模式与其它模式
中介者模式(Mediator):通过封装复杂的更新语义,ChangeManager充当目标和观察者之间的中介者。
单例模式(singleton模式):ChangeManager可使用Singleton模式来保证它是唯一的并且是可全局访问的。
七、观察者模式PHP示例

<?php
/**
 * 抽象主题角色
 */
interface Subject {
 
  /**
   * 增加一个新的观察者对象
   * @param Observer $observer
   */
  public function attach(Observer $observer);
 
  /**
   * 删除一个已注册过的观察者对象
   * @param Observer $observer
   */
  public function detach(Observer $observer);
 
  /**
   * 通知所有注册过的观察者对象
   */
  public function notifyObservers();
}
 
/**
 * 具体主题角色
 */
class ConcreteSubject implements Subject {
 
  private $_observers;
 
  public function __construct() {
    $this->_observers = array();
  }
 
  /**
   * 增加一个新的观察者对象
   * @param Observer $observer
   */
  public function attach(Observer $observer) {
    return array_push($this->_observers, $observer);
  }
 
  /**
   * 删除一个已注册过的观察者对象
   * @param Observer $observer
   */
  public function detach(Observer $observer) {
    $index = array_search($observer, $this->_observers);
    if ($index === FALSE || ! array_key_exists($index, $this->_observers)) {
      return FALSE;
    }
 
    unset($this->_observers[$index]);
    return TRUE;
  }
 
  /**
   * 通知所有注册过的观察者对象
   */
  public function notifyObservers() {
    if (!is_array($this->_observers)) {
      return FALSE;
    }
 
    foreach ($this->_observers as $observer) {
      $observer->update();
    }
 
    return TRUE;
  }
 
}
 
/**
 * 抽象观察者角色
 */
interface Observer {
 
  /**
   * 更新方法
   */
  public function update();
}
 
class ConcreteObserver implements Observer {
 
  /**
   * 观察者的名称
   * @var <type>
   */
  private $_name;
 
  public function __construct($name) {
    $this->_name = $name;
  }
 
  /**
   * 更新方法
   */
  public function update() {
    echo 'Observer', $this->_name, ' has notified.<br />';
  }
 
}
 
/**
 * 客户端
 */
class Client {
 
  /**
   * Main program.
   */
  public static function main() {
    $subject = new ConcreteSubject();
 
    /* 添加第一个观察者 */
    $observer1 = new ConcreteObserver('Martin');
    $subject->attach($observer1);
 
    echo '<br /> The First notify:<br />';
    $subject->notifyObservers();
 
    /* 添加第二个观察者 */
    $observer2 = new ConcreteObserver('phppan');
    $subject->attach($observer2);
 
    echo '<br /> The Second notify:<br />';
    $subject->notifyObservers();
 
    /* 删除第一个观察者 */
    $subject->detach($observer1);
 
    echo '<br /> The Third notify:<br />';
    $subject->notifyObservers();
  }
 
}
 
Client::main();
?>

以上就是使用php实现观察者模式的代码,还有一些关于观察者模式的概念区分,希望对大家的学习有所帮助。

PHP 相关文章推荐
php基础知识:控制结构
Dec 13 PHP
实现了一个PHP5的getter/setter基类的代码
Feb 25 PHP
PHP内核介绍及扩展开发指南―基础知识
Sep 11 PHP
PHP代码网站如何防范SQL注入漏洞攻击建议分享
Mar 01 PHP
phpExcel导出大量数据出现内存溢出错误的解决方法
Feb 28 PHP
thinkphp 一个页面使用2次分页的实现方法
Jul 15 PHP
php中sql注入漏洞示例 sql注入漏洞修复
Jan 24 PHP
PHP调用VC编写的COM组件实例
Mar 29 PHP
PHP中的类型约束介绍
May 11 PHP
PHP数组操作类实例
Jul 11 PHP
项目中应用Redis+Php的场景
May 22 PHP
php字符集转换
Jan 23 PHP
PHP判断手机是IOS还是Android
Dec 09 #PHP
PHP的Yii框架的常用日志操作总结
Dec 08 #PHP
Linux系统下使用XHProf和XHGui分析PHP运行性能
Dec 08 #PHP
thinkPHP中create方法与令牌验证实例浅析
Dec 08 #PHP
详解PHP的Yii框架中日志的相关配置及使用
Dec 08 #PHP
UPUPW 更新 64 位 Apache 系列 PHP 7.0 正式版
Dec 08 #PHP
学习php设计模式 php实现模板方法模式
Dec 08 #PHP
You might like
如何开始收听短波广播
2021/03/01 无线电
PHP SQLite类
2009/05/07 PHP
php中curl和file_get_content的区别
2014/05/10 PHP
PHP导出Excel实例讲解
2016/01/24 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
javascript 密码框防止用户粘贴和复制的实现代码
2014/02/17 Javascript
理解jquery事件冒泡
2016/01/03 Javascript
浅析javascript函数表达式
2016/02/10 Javascript
jQuery.deferred对象使用详解
2016/03/18 Javascript
基于javascript实现九宫格大转盘效果
2020/05/28 Javascript
JavaScript设计模式之单体模式全面解析
2016/09/09 Javascript
Angular.js自定义指令学习笔记实例
2017/02/24 Javascript
解决js ajax同步请求造成浏览器假死的问题
2018/01/18 Javascript
关于RxJS Subject的学习笔记
2018/12/05 Javascript
Vue实现页面添加水印功能
2019/11/09 Javascript
在Vue中实现随hash改变响应菜单高亮
2020/03/09 Javascript
vue实现选中效果
2020/10/07 Javascript
[02:42]2014DOTA2国际邀请赛 三冰专访:我会打到Ti20
2014/07/13 DOTA
python 队列详解及实例代码
2016/10/18 Python
python开发简易版在线音乐播放器
2017/03/03 Python
python里使用正则表达式的组嵌套实例详解
2017/10/24 Python
python 把文件中的每一行以数组的元素放入数组中的方法
2018/04/29 Python
python使用RNN实现文本分类
2018/05/24 Python
PyTorch读取Cifar数据集并显示图片的实例讲解
2018/07/27 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
使用CSS3实现SVG路径描边动画效果入门教程
2019/10/21 HTML / CSS
CSS3制作轮播图的一种方法
2019/11/11 HTML / CSS
解决canvas转base64/jpeg时透明区域变成黑色背景的方法
2016/10/23 HTML / CSS
酒吧员工的岗位职责
2013/11/26 职场文书
医院总经理岗位职责
2014/02/04 职场文书
党员公开承诺书和承诺事项
2014/03/25 职场文书
农村葬礼主持词
2014/03/31 职场文书
红色经典观后感
2015/06/18 职场文书
堂吉诃德读书笔记
2015/06/30 职场文书
新学期新寄语,献给新生们!
2019/11/15 职场文书
导游词之江苏溱潼古镇
2019/11/27 职场文书