学习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 相关文章推荐
计数器详细设计
Oct 09 PHP
信用卡效验程序
Oct 09 PHP
让PHP支持页面回退的两种方法
Jan 10 PHP
php的POSIX 函数以及进程测试的深入分析
Jun 03 PHP
phpphp图片采集后按原路径保存图片示例
Feb 18 PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
Sep 23 PHP
php中strtotime函数用法详解
Nov 15 PHP
php中session_id()函数详细介绍,会话id生成过程及session id长度
Sep 23 PHP
PHP使用strstr()函数获取指定字符串后所有字符的方法
Jan 07 PHP
php微信公众号开发之校园图书馆
Oct 20 PHP
针对PHP开发安全问题的相关总结
Mar 22 PHP
如何利用PHP实现上传图片功能详解
Sep 24 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
星际初学者游戏中永远要做的事
2020/03/04 星际争霸
PHP的switch判断语句的“高级”用法详解
2014/10/01 PHP
php面向对象中static静态属性与方法的内存位置分析
2015/02/08 PHP
CI(CodeIgniter)框架视图中加载视图的方法
2017/03/24 PHP
项目实践之javascript技巧
2007/12/06 Javascript
JQuery操作表格(隔行着色,高亮显示,筛选数据)
2012/02/23 Javascript
javascript中方便增删改cookie的一个类
2012/10/11 Javascript
jquery实现的缩略图预览滑块实例
2015/06/25 Javascript
浅析JavaScript作用域链、执行上下文与闭包
2016/02/01 Javascript
js拖拽的原型声明和用法总结
2016/04/04 Javascript
jQuery实现遮罩层登录对话框
2016/12/29 Javascript
js模拟微博发布消息
2017/02/23 Javascript
js实现带进度条提示的多视频上传功能
2020/12/13 Javascript
vue 自定义组件 v-model双向绑定、 父子组件同步通信的多种写法
2017/11/27 Javascript
Vue中的无限加载vue-infinite-loading的方法
2018/04/08 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
Angular8 实现table表格表头固定效果
2020/01/03 Javascript
python WindowsError的错误代码详解
2017/07/23 Python
Python中顺序表的实现简单代码分享
2018/01/09 Python
Python基于递归算法求最小公倍数和最大公约数示例
2018/07/27 Python
实例讲解Python中整数的最大值输出
2019/03/17 Python
浅析PyTorch中nn.Linear的使用
2019/08/18 Python
python实现的读取网页并分词功能示例
2019/10/29 Python
基于Python批量生成指定尺寸缩略图代码实例
2019/11/20 Python
python MultipartEncoder传输zip文件实例
2020/04/07 Python
Django serializer优化类视图的实现示例
2020/07/16 Python
Aerosoles爱柔仕官网:美国舒软女鞋品牌
2017/07/17 全球购物
英国顶级水晶珠宝零售商之一:Tresor Paris
2019/04/27 全球购物
美国鲜花递送:UrbanStems
2021/01/04 全球购物
Jones Bootmaker官网:优质靴子和鞋子在线
2020/11/30 全球购物
linux面试题参考答案(3)
2012/09/13 面试题
《藏戏》教学反思
2014/02/11 职场文书
死亡赔偿协议书
2015/01/28 职场文书
销售开票员岗位职责
2015/04/15 职场文书
导游词之泰山玉皇顶
2019/12/23 职场文书
MyBatis核心源码深度剖析SQL语句执行过程
2022/05/20 Java/Android