学习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中函数内引用全局变量的方法
Oct 20 PHP
Windows Apache2.2.11及Php5.2.9-1的安装与配置方法
Jun 08 PHP
PHP parse_url 一个好用的函数
Oct 03 PHP
PHP数组操作汇总 php数组的使用技巧
Jul 17 PHP
apache+codeigniter 通过.htcaccess做动态二级域名解析
Jul 01 PHP
PHP函数之日期时间函数date()使用详解
Sep 09 PHP
PHP新建类问题分析及解决思路
Nov 19 PHP
php session的锁和并发
Jan 22 PHP
CentOS 7.2 下编译安装PHP7.0.10+MySQL5.7.14+Nginx1.10.1的方法详解(mini版本)
Sep 01 PHP
ThinkPHP防止重复提交表单的方法实例分析
May 10 PHP
PHP去除空数组且数组键名重置的讲解
Feb 28 PHP
TP3.2.3框架文件上传操作实例详解
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
关于WordPress的SEO优化相关的一些PHP页面脚本技巧
2015/12/10 PHP
PHP实现的网站目录扫描索引工具
2016/09/08 PHP
PHP如何搭建百度Ueditor富文本编辑器
2018/09/21 PHP
JS高级笔记
2011/07/13 Javascript
jquery 无限级联菜单案例分享
2013/03/26 Javascript
Javascript 完美运动框架(逐行分析代码,让你轻松了运动的原理)
2015/01/23 Javascript
JS实现网页背景颜色与select框中颜色同时变化的方法
2015/02/27 Javascript
AngularJS前端页面操作之用户修改密码功能示例
2017/03/27 Javascript
jQuery Datatable 多个查询条件自定义提交事件(推荐)
2017/08/24 jQuery
详解VUE2.X过滤器的使用方法
2018/01/11 Javascript
vue.js响应式原理解析与实现
2020/06/22 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
2018/09/30 Javascript
vue实现todolist基本功能以及数据存储功能实例详解
2019/04/11 Javascript
Angular6项目打包优化的实现方法
2019/12/15 Javascript
JavaScript实现指定数量的并发限制的示例代码
2020/03/10 Javascript
解决vue项目打包上服务器显示404错误,本地没出错的问题
2020/11/03 Javascript
[01:46]2018完美盛典章节片——坚守
2018/12/17 DOTA
python getopt 参数处理小示例
2009/06/09 Python
python读写ini文件示例(python读写文件)
2014/03/25 Python
Python自动化部署工具Fabric的简单上手指南
2016/04/19 Python
Python中is与==判断的区别
2017/03/28 Python
Python通过Pygame绘制移动的矩形实例代码
2018/01/03 Python
Python数据类型之Number数字操作实例详解
2019/05/08 Python
详解Python 实现 ZeroMQ 的三种基本工作模式
2020/03/24 Python
详解快速开发基于 HTML5 网络拓扑图应用
2018/01/08 HTML / CSS
C语言变量的命名规则都有哪些
2013/12/27 面试题
应届生服装设计自我评价
2013/09/20 职场文书
会计系毕业个人自荐信格式
2013/09/23 职场文书
电子商务专业学生的学习自我评价
2013/10/27 职场文书
财务主管自我鉴定
2014/01/17 职场文书
企业授权委托书范本
2014/04/02 职场文书
幼儿园安全工作总结2015
2015/04/20 职场文书
再读《皇帝的新衣》的读后感悟!
2019/08/07 职场文书
Python Django 后台管理之后台模型属性详解
2021/04/25 Python
CSS 使用 resize 实现图片拖拽切换预览功能(强大功能)
2021/08/23 HTML / CSS
Java实战之课程信息管理系统的实现
2022/04/01 Java/Android