学习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 相关文章推荐
使用无限生命期Session的方法
Oct 09 PHP
简单的页面缓冲技术
Oct 09 PHP
PHP显示今天、今月、上月、今年的起点/终点时间戳的代码
May 25 PHP
解析php中的fopen()函数用打开文件模式说明
Jun 20 PHP
如何解决CI框架的Disallowed Key Characters错误提示
Jul 05 PHP
destoon安装出现Internal Server Error的解决方法
Jun 21 PHP
PHP实现采集中国天气网未来7天天气
Oct 15 PHP
php实现表单多按钮提交action的处理方法
Oct 24 PHP
学习php设计模式 php实现访问者模式(Visitor)
Dec 07 PHP
Yii2实现多域名跨域同步登录退出
Feb 04 PHP
php事务回滚简单实现方法示例
Mar 28 PHP
Laravel框架路由设置与使用示例
Jun 12 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
德生S2000南麂列岛台湾FM收听记录
2021/03/02 无线电
生成ubuntu自动切换壁纸xml文件的php代码
2010/07/17 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
2013/01/29 PHP
php实现水仙花数示例分享
2014/04/03 PHP
PHP微信支付开发实例
2016/06/22 PHP
谈谈从phpinfo中能获取哪些值得注意的信息
2017/03/28 PHP
php数据结构之顺序链表与链式线性表示例
2018/01/22 PHP
PHP命名空间namespace及use的简单用法分析
2018/08/03 PHP
解决laravel session失效的问题
2019/10/14 PHP
jquery下checked取值问题的解决方法
2012/08/09 Javascript
js模仿jquery的写法示例代码
2013/06/16 Javascript
JS实现简单的键盘打字的效果
2015/04/24 Javascript
jQuery仿京东商城楼梯式导航定位菜单
2016/07/25 Javascript
深入浅析JS Function()构造函数
2016/08/22 Javascript
jQuery禁用快捷键例如禁用F5刷新 禁用右键菜单等的简单实现
2016/08/31 Javascript
Vue.js组件通信之自定义事件详解
2019/10/19 Javascript
Vue watch响应数据实现方法解析
2020/07/10 Javascript
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
2017/08/21 Python
利用Python查看目录中的文件示例详解
2017/08/28 Python
python数据类型之间怎么转换技巧分享
2019/08/20 Python
Python单元测试与测试用例简析
2019/11/09 Python
html5 Canvas画图教程(1)—画图的基本常识
2013/01/09 HTML / CSS
JENNIFER BEHR官网:各种耳环和发饰
2020/06/07 全球购物
波兰汽车配件网上商店:iParts.pl
2020/09/08 全球购物
三万活动总结
2014/04/28 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
计算机售后服务承诺书
2014/05/30 职场文书
员工安全生产责任书
2014/07/22 职场文书
自强自立美德少年事迹材料
2014/08/16 职场文书
大学生军训自我鉴定范文
2014/09/18 职场文书
学生上课看漫画的检讨书
2014/09/26 职场文书
区域销售经理岗位职责
2015/04/02 职场文书
《乘法分配律》教学反思
2016/02/24 职场文书
幼儿园教师辞职信
2019/06/21 职场文书
总结一些Java常用的加密算法
2021/06/11 Java/Android
全网非常详细的pytest配置文件
2022/07/15 Python