学习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操作文件方法问答
Mar 16 PHP
PHP 模拟$_PUT实现代码
Mar 15 PHP
PHP与MongoDB简介|安全|M+PHP应用实例详解
Jun 17 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十一)
Jun 25 PHP
PHP闭包函数详解
Feb 13 PHP
PHP邮件群发机实现代码
Feb 16 PHP
Laravel路由设定和子路由设定实例分析
Mar 30 PHP
PHP微信开发之有道翻译
Jun 23 PHP
PHP递归实现快速排序的方法示例
Dec 18 PHP
PHP进阶学习之Geo的地图定位算法详解
Jun 19 PHP
关于php开启错误提示的总结
Sep 24 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
Feb 27 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
PHP 图片上传实现代码 带详细注释
2010/04/29 PHP
php生成随机数的三种方法
2014/09/10 PHP
php实现QQ空间获取当前用户的用户名并生成图片
2015/07/25 PHP
jquery1.10给新增元素绑定事件的方法
2014/03/06 Javascript
JavaScript两种跨域技术全面介绍
2014/04/16 Javascript
javascript实现10个球随机运动、碰撞实例详解
2015/07/08 Javascript
Nodejs的express使用教程
2015/11/23 NodeJs
深入解析JavaScript中函数的Currying柯里化
2016/03/19 Javascript
JS组件Bootstrap实现图片轮播效果
2016/05/16 Javascript
DIV+CSS+jQ实现省市联动可扩展
2016/06/22 Javascript
Javascript 创建类并动态添加属性及方法的简单实现
2016/10/20 Javascript
通过原生JS实现为元素添加事件的方法
2016/11/23 Javascript
VUE开发一个图片轮播的组件示例代码
2017/03/06 Javascript
npm配置国内镜像资源+淘宝镜像的方法
2018/09/07 Javascript
JavaScript实现与使用发布/订阅模式详解
2019/01/19 Javascript
jquery实现二级导航下拉菜单效果实例
2019/05/14 jQuery
Vue中的组件及路由使用实例代码详解
2019/05/22 Javascript
更强大的vue ssr实现预取数据的方式
2019/07/19 Javascript
搭建vscode+vue环境的详细教程
2020/08/31 Javascript
vue-cli3自动消除console.log()的调试信息方式
2020/10/21 Javascript
用Python写的图片蜘蛛人代码
2012/08/27 Python
Python开发最牛逼的IDE——pycharm
2018/08/01 Python
Python给图像添加噪声具体操作
2019/03/03 Python
Django之提交表单与前后端交互的方法
2019/07/19 Python
Django项目基础配置和基本使用过程解析
2019/11/25 Python
使用PyCharm官方中文语言包汉化PyCharm
2020/11/18 Python
Python用摘要算法生成token及检验token的示例代码
2020/12/01 Python
html5视频播放_动力节点Java学院整理
2017/07/13 HTML / CSS
HTML5 WebGL 实现民航客机飞行监控系统
2019/07/25 HTML / CSS
《伯牙绝弦》教学反思
2014/03/02 职场文书
网站创业计划书
2014/04/30 职场文书
网络文明传播志愿者活动方案
2014/08/20 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
导游词之宁夏贺兰山岩画
2019/11/08 职场文书
jquery插件实现搜索历史
2021/04/24 jQuery
教你使用Ubuntu搭建DNS服务器
2022/09/23 Servers