php观察者模式应用场景实例详解


Posted in PHP onFebruary 03, 2017

本文实例讲述了php观察者模式的应用。分享给大家供大家参考,具体如下:

<?php
/**
 * 观察者模式应用场景实例
 *
 * 免责声明:本文只是以哈票网举例,示例中并未涉及哈票网任何业务代码,全部原创,如有雷同,纯属巧合。
 *
 * 场景描述:
 * 哈票以购票为核心业务(此模式不限于该业务),但围绕购票会产生不同的其他逻辑,如:
 * 1、购票后记录文本日志
 * 2、购票后记录数据库日志
 * 3、购票后发送短信
 * 4、购票送抵扣卷、兑换卷、积分
 * 5、其他各类活动等
 *
 * 传统解决方案:
 * 在购票逻辑等类内部增加相关代码,完成各种逻辑。
 *
 * 存在问题:
 * 1、一旦某个业务逻辑发生改变,如购票业务中增加其他业务逻辑,需要修改购票核心文件、甚至购票流程。
 * 2、日积月累后,文件冗长,导致后续维护困难。
 *
 * 存在问题原因主要是程序的"紧密耦合",使用观察模式将目前的业务逻辑优化成"松耦合",达到易维护、易修改的目的,
 * 同时也符合面向接口编程的思想。
 *
 * 观察者模式典型实现方式:
 * 1、定义2个接口:观察者(通知)接口、被观察者(主题)接口
 * 2、定义2个类,观察者对象实现观察者接口、主题类实现被观者接口
 * 3、主题类注册自己需要通知的观察者
 * 4、主题类某个业务逻辑发生时通知观察者对象,每个观察者执行自己的业务逻辑。
 *
 * 示例:如以下代码
 *
 */
 date_default_timezone_set('PRC'); //设置中国时区
#===================定义观察者、被观察者接口============
/**
 *
 * 观察者接口(通知接口)
 *
 */
interface ITicketObserver //观察者接口
{
  function onBuyTicketOver($sender, $args); //得到通知后调用的方法
}
/**
 *
 * 主题接口
 *
 */
interface ITicketObservable //被观察对象接口
{
  function addObserver($observer); //提供注册观察者方法
}
#====================主题类实现========================
/**
 *
 * 主题类(购票)
 *
 */
class HipiaoBuy implements ITicketObservable { //实现主题接口(被观察者)
  private $_observers = array (); //通知数组(观察者)
  public function buyTicket($ticket) //购票核心类,处理购票流程
{
    // TODO 购票逻辑
    //循环通知,调用其onBuyTicketOver实现不同业务逻辑
    foreach ( $this->_observers as $obs )
      $obs->onBuyTicketOver ( $this, $ticket ); //$this 可用来获取主题类句柄,在通知中使用
  }
  //添加通知
  public function addObserver($observer) //添加N个通知
{
    $this->_observers [] = $observer;
  }
}
#=========================定义多个通知====================
//短信日志通知
class HipiaoMSM implements ITicketObserver {
  public function onBuyTicketOver($sender, $ticket) {
    echo (date ( 'Y-m-d H:i:s' ) . " 短信日志记录:购票成功:$ticket<br>");
  }
}
//文本日志通知
class HipiaoTxt implements ITicketObserver {
  public function onBuyTicketOver($sender, $ticket) {
    echo (date ( 'Y-m-d H:i:s' ) . " 文本日志记录:购票成功:$ticket<br>");
  }
}
//抵扣卷赠送通知
class HipiaoDiKou implements ITicketObserver {
  public function onBuyTicketOver($sender, $ticket) {
    echo (date ( 'Y-m-d H:i:s' ) . " 赠送抵扣卷:购票成功:$ticket 赠送10元抵扣卷1张。<br>");
  }
}
#============================用户购票====================
$buy = new HipiaoBuy ();
$buy->addObserver ( new HipiaoMSM () ); //根据不同业务逻辑加入各种通知
$buy->addObserver ( new HipiaoTxt () );
$buy->addObserver ( new HipiaoDiKou () );
//购票
$buy->buyTicket ( "一排一号" );
?>

运行结果如下:

2017-02-03 10:25:45 短信日志记录:购票成功:一排一号
2017-02-03 10:25:45 文本日志记录:购票成功:一排一号
2017-02-03 10:25:45 赠送抵扣卷:购票成功:一排一号 赠送10元抵扣卷1张。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP遍历某个目录下的所有文件和子文件夹的实现代码
Jun 28 PHP
关于php程序报date()警告的处理(date_default_timezone_set)
Oct 22 PHP
使用php计算排列组合的方法
Nov 13 PHP
php实现在线生成条形码示例分享(条形码生成器)
Dec 30 PHP
PHP编程中的__clone()方法使用详解
Nov 27 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
PHP异常处理定义与使用方法分析
Jul 25 PHP
PHP基于redis计数器类定义与用法示例
Feb 08 PHP
PHP排序算法之希尔排序(Shell Sort)实例分析
Apr 20 PHP
YII框架http缓存操作示例
Apr 29 PHP
PHP针对redis常用操作实例详解
Aug 17 PHP
PHP解密支付宝小程序的加密数据、手机号的示例代码
Feb 26 PHP
PHP CURL采集百度搜寻结果图片不显示问题的解决方法
Feb 03 #PHP
php使用curl代理实现抓取数据的方法
Feb 03 #PHP
php实现xml转换数组的方法示例
Feb 03 #PHP
php删除txt文件指定行及按行读取txt文档数据的方法
Jan 30 #PHP
php指定长度分割字符串str_split函数用法示例
Jan 30 #PHP
php使用自定义函数实现汉字分割替换功能示例
Jan 30 #PHP
PHPExcel在linux环境下导出报500错误的解决方法
Jan 26 #PHP
You might like
真正面向对象编程:PHP5.01发布
2006/10/09 PHP
php实现字符串首字母转换成大写的方法
2015/03/17 PHP
关于__defineGetter__ 和__defineSetter__的说明
2007/05/12 Javascript
JavaScript 数组的 uniq 方法
2008/01/23 Javascript
javascript中的107个基础知识收集整理 推荐
2010/03/29 Javascript
jQuery.each()用法分享
2012/07/31 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
2014/06/30 Javascript
JavaScript删除数组元素的方法
2015/03/20 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
2015/04/27 Javascript
jQuery实现的指纹扫描效果实例(附演示与demo源码下载)
2016/01/26 Javascript
jQuery UI库中dialog对话框功能使用全解析
2016/04/23 Javascript
根据Bootstrap Paginator改写的js分页插件
2016/12/25 Javascript
简单实现js轮播图效果
2017/07/14 Javascript
node.js支持多用户web终端实现及安全方案
2017/11/29 Javascript
es6 symbol的实现方法示例
2019/04/02 Javascript
JS关闭子窗口并且刷新上一个窗口的实现示例
2020/03/10 Javascript
vue实现轮播图帧率播放
2021/01/26 Vue.js
[01:09]DOTA2次级职业联赛 - 99战队宣传片
2014/12/01 DOTA
[33:28]完美世界DOTA2联赛PWL S3 PXG vs GXR 第三场 12.19
2020/12/24 DOTA
Python3里的super()和__class__使用介绍
2015/04/23 Python
Django实现的自定义访问日志模块示例
2017/06/23 Python
详解python中的线程与线程池
2019/05/10 Python
基于YUV 数据格式详解及python实现方式
2019/12/09 Python
Python3.x+迅雷x 自动下载高分电影的实现方法
2020/01/12 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
美国知名的女性服饰品牌:LOFT(洛芙特)
2016/08/05 全球购物
欧舒丹美国官网:L’Occitane美国
2018/02/23 全球购物
乐高官方旗舰店:LEGO积木玩具
2019/04/06 全球购物
会计毕业生求职简历的自我评价
2013/10/20 职场文书
五一家具促销方案
2014/01/10 职场文书
商场租赁意向书
2014/07/30 职场文书
党的群众路线教育实践活动领导班子整改措施
2014/09/30 职场文书
青年人初次创业的“五不要”
2019/08/23 职场文书
Python 发送SMTP邮件的简单教程
2021/06/24 Python
java调用Restful接口的三种方法
2021/08/23 Java/Android
Nginx配置使用详解
2022/07/07 Servers