学习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 获取完整url地址
Dec 20 PHP
PHP的加密方式及原理
Jun 14 PHP
关于php正则匹配汉字的方法介绍
Apr 25 PHP
PHPExcel内存泄漏问题解决方法
Jan 23 PHP
php实现汉字验证码和算式验证码的方法
Mar 07 PHP
ThinkPHP数据操作方法总结
Sep 28 PHP
php版微信公众平台入门教程之开发者认证的方法
Sep 26 PHP
PHP编写daemon process 实例详解
Nov 13 PHP
PHP 中使用ajax时一些常见错误总结整理
Feb 27 PHP
PHP大文件分割上传 PHP分片上传
Aug 28 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
Feb 19 PHP
windows系统php环境安装swoole具体步骤
Mar 04 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
Windows2003 下 MySQL 数据库每天自动备份
2006/12/21 PHP
PHP 使用位运算实现四则运算的代码
2021/03/09 PHP
Javascript里使用Dom操作Xml
2007/01/22 Javascript
基于jQuery捕获超链接事件进行局部刷新代码
2012/05/10 Javascript
onclick与listeners的执行先后问题详细解剖
2013/01/07 Javascript
js 获取input点选按钮的值的方法
2014/04/14 Javascript
浅谈javascript 归并方法
2015/01/21 Javascript
利用jQuery实现WordPress中@的ID悬浮显示评论内容
2015/12/11 Javascript
深入分析Javascript事件代理
2016/01/30 Javascript
你一定会收藏的Nodejs代码片段
2016/02/04 NodeJs
AngularJS基础 ng-list 指令详解及示例代码
2016/08/02 Javascript
jQuery多文件异步上传带进度条实例代码
2016/08/16 Javascript
javascript ES6中箭头函数注意细节小结
2017/02/17 Javascript
element ui 对话框el-dialog关闭事件详解
2018/02/26 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
JS校验与最终登陆界面功能完整示例
2020/01/13 Javascript
JS实现放大镜效果
2020/09/21 Javascript
复制粘贴功能的Python程序
2008/04/04 Python
python查找指定具有相同内容文件的方法
2015/06/28 Python
Python绑定方法与非绑定方法详解
2017/08/18 Python
Python输出带颜色的字符串实例
2017/10/10 Python
python内置函数:lambda、map、filter简单介绍
2017/11/16 Python
Python 数据处理库 pandas 入门教程基本操作
2018/04/19 Python
解决pycharm回车之后不能换行或不能缩进的问题
2019/01/16 Python
python下载微信公众号相关文章
2019/02/26 Python
Python随机函数库random的使用方法详解
2019/08/21 Python
pytorch如何冻结某层参数的实现
2020/01/10 Python
小天鹅官方商城:LittleSwan
2017/06/16 全球购物
丝芙兰加拿大官方网站:SEPHORA加拿大
2018/11/20 全球购物
美国花园雕像和家居装饰网上商店:Design Toscano
2019/03/09 全球购物
怎样声明一个匿名的内部类
2016/06/01 面试题
结婚喜宴家长答谢词
2014/01/15 职场文书
奥巴马竞选演讲稿
2014/05/15 职场文书
2015年人事专员工作总结
2015/04/29 职场文书
幼儿园教学反思范文
2016/03/02 职场文书
2019单位介绍信怎么写
2019/06/24 职场文书