学习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的FTP学习(四)
Oct 09 PHP
PHP中常用数组处理方法实例分析
Aug 30 PHP
PHP如何解决网站大流量与高并发的问题
Jun 25 PHP
用php解析html的实现代码
Aug 08 PHP
zend optimizer在wamp的基础上安装图文教程
Oct 26 PHP
discuz加密解密函数使用方法和中文注释
Jan 21 PHP
PHP基于工厂模式实现的计算器实例
Jul 16 PHP
基于PHP实现通过照片获取ip地址
Apr 26 PHP
PHP处理Ajax请求与Ajax跨域问题
Feb 13 PHP
PHP fopen函数用法实例讲解
Feb 15 PHP
PHP实现随机发放扑克牌
Apr 21 PHP
PHP Ajax跨域问题解决方案代码实例
Aug 01 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同时支持GIF、png、JPEG
2006/10/09 PHP
用PHP查询搜索引擎排名位置的代码
2010/01/05 PHP
防止本地用户用fsockopen DDOS攻击对策
2011/11/02 PHP
PHP模拟asp中response类实现方法
2015/08/08 PHP
thinkphp微信开发(消息加密解密)
2015/12/02 PHP
php结合ajax实现手机发红包的案例
2016/10/13 PHP
PHP+JavaScript实现无刷新上传图片
2017/02/21 PHP
通过js脚本复制网页上的一个表格的不错实现方法
2006/12/29 Javascript
Firefox window.close()的使用注意事项
2009/04/11 Javascript
js动画效果制件让图片组成动画代码分享
2014/01/14 Javascript
利用Angular.js限制textarea输入的字数
2016/10/20 Javascript
理解JavaScript原型链
2016/10/25 Javascript
jQuery.datatables.js插件用法及api实例详解
2016/10/28 Javascript
利用n 升级工具升级Node.js版本及在mac环境下的坑
2017/02/15 Javascript
JavaScript中常见内置函数用法示例
2018/05/14 Javascript
vue如何安装使用Quill富文本编辑器
2018/09/21 Javascript
如何获取vue单文件自身源码路径
2019/05/06 Javascript
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
pycharm 使用心得(一)安装和首次使用
2014/06/05 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
python 实现在一张图中绘制一个小的子图方法
2019/07/07 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧(自定义信号与槽)详解与实例
2020/03/06 Python
python 图像判断,清晰度(明暗),彩色与黑白实例
2020/06/04 Python
详解Flask前后端分离项目案例
2020/07/24 Python
详解python中的三种命令行模块(sys.argv,argparse,click)
2020/12/15 Python
CSS3实现复选框动画特效示例代码
2016/09/27 HTML / CSS
css3实现小箭头各种图形效果
2020/07/08 HTML / CSS
Nike英国官网:Nike.com (UK)
2017/02/13 全球购物
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
C++:局部变量能否和全局变量重名
2014/03/03 面试题
应届生学校辅导员求职信
2013/11/07 职场文书
2014企业领导班子四风对照检查材料思想汇报
2014/09/17 职场文书
社区党员群众路线教育实践活动心得体会
2014/11/03 职场文书
2014年综治维稳工作总结
2014/11/17 职场文书
原生JS封装vue Tab切换效果
2021/04/28 Vue.js
Golang原生rpc(rpc服务端源码解读)
2022/04/07 Golang