学习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编程最快明白》第四讲:日期、表单接收、session、cookie
Nov 01 PHP
apache+php完美解决301重定向的两种方法
Jun 08 PHP
解析PHP中的内存管理,PHP动态分配和释放内存
Jun 28 PHP
php生成图形验证码几种方法小结
Aug 15 PHP
php中stream(流)的用法
Mar 25 PHP
php生成xml时添加CDATA标签的方法
Oct 17 PHP
CodeIgniter针对lighttpd服务器URL重写的方法
Jun 10 PHP
PHP随机数 C扩展随机数
May 04 PHP
tp5(thinkPHP5框架)使用DB实现批量删除功能示例
May 28 PHP
thinkphp5.1 框架钩子和行为用法实例分析
May 25 PHP
用php实现分页效果的示例代码
Dec 10 PHP
如何用PHP实现多线程编程
May 26 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
smtp邮件发送一例
2006/10/09 PHP
PHP获得用户使用的代理服务器ip即真实ip
2006/12/31 PHP
Yii不依赖Model的表单生成器用法实例
2014/12/04 PHP
php生成图片验证码的方法
2016/04/15 PHP
Yii中的relations数据关联查询及统计功能用法详解
2016/07/14 PHP
浅谈PHP的反射API
2017/02/26 PHP
jQuery的三种$()
2009/12/30 Javascript
ExtJS 入门
2010/10/29 Javascript
使用insertAfter()方法在现有元素后添加一个新元素
2014/05/28 Javascript
JQuery分屏指示器图片轮换效果实例
2015/05/21 Javascript
javascript原生ajax写法分享
2016/04/10 Javascript
jQuery Easyui快速入门教程
2016/08/21 Javascript
简易的JS计算器实现代码
2016/10/18 Javascript
网络传输协议(http协议)
2016/11/18 Javascript
微信小程序 详解页面跳转与返回并回传数据
2017/02/13 Javascript
原生js编写2048小游戏
2017/03/17 Javascript
vue.js如何更改默认端口号8080为指定端口的方法
2017/07/14 Javascript
如何在Vue.js中实现标签页组件详解
2019/01/02 Javascript
详解NodeJs项目 CentOs linux服务器线上部署
2019/09/16 NodeJs
Vue实现商品飞入购物车效果(电商项目)
2019/11/26 Javascript
python实现多线程暴力破解登陆路由器功能代码分享
2015/01/04 Python
python制作花瓣网美女图片爬虫
2015/10/28 Python
python在文本开头插入一行的实例
2018/05/02 Python
python3模块smtplib实现发送邮件功能
2018/05/22 Python
python验证码识别教程之灰度处理、二值化、降噪与tesserocr识别
2018/06/04 Python
Python实现的简单排列组合算法示例
2018/07/04 Python
python算法题 链表反转详解
2019/07/02 Python
html5 sessionStorage会话存储_动力节点Java学院整理
2017/07/06 HTML / CSS
捷克原创男装和女装购物网站:Bolf.cz
2018/04/28 全球购物
法律工作求职自荐信
2013/10/31 职场文书
《一件运动衫》教学反思
2014/02/19 职场文书
超市开学活动方案
2014/03/01 职场文书
中学清明节活动总结
2014/07/04 职场文书
反腐倡廉警示教育活动心得体会
2014/09/04 职场文书
2015年班主任个人工作总结
2015/03/31 职场文书
商场营业员岗位职责
2015/04/14 职场文书