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新手上路(二)
Oct 09 PHP
初级的用php写的采集程序
Mar 16 PHP
也谈php网站在线人数统计
Apr 09 PHP
php session_start()关于Cannot send session cache limiter - headers already sent错误解决方法
Nov 27 PHP
php连接Access数据库错误及解决方法
Jun 20 PHP
PHP文件锁定写入实例解析
Jul 14 PHP
php socket实现的聊天室代码分享
Aug 16 PHP
php强制运行广告的方法
Dec 01 PHP
php中最简单的字符串匹配算法
Dec 16 PHP
CI框架入门之MVC简单示例
Nov 21 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
Apr 12 PHP
laravel框架模型和数据库基础操作实例详解
Jan 25 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
LotusPhp笔记之:Logger组件的使用方法
2013/05/06 PHP
PHP将两个关联数组合并函数提高函数效率
2014/03/18 PHP
开启PHP的伪静态模式
2015/12/31 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
2019/10/16 PHP
js下弹出窗口的变通
2007/04/18 Javascript
childNodes.length与children.length的区别
2009/05/14 Javascript
javascript 文章截取部分无损html显示实现代码
2010/05/04 Javascript
JavaScript之Getters和Setters 平台支持等详细介绍
2012/12/07 Javascript
JS异常处理的一个想法(sofish)
2013/03/14 Javascript
Json和Jsonp理论实例代码详解
2013/11/15 Javascript
父节点获取子节点的字符串示例代码
2014/02/26 Javascript
node.js中的events.emitter.once方法使用说明
2014/12/10 Javascript
jQuery实现购物车表单自动结算效果实例
2015/08/10 Javascript
Struts2+jquery.form.js实现图片与文件上传的方法
2016/05/05 Javascript
浅谈js中startsWith 函数不能在任何浏览器兼容的问题
2017/03/01 Javascript
Vue的watch和computed方法的使用及区别介绍
2018/09/06 Javascript
小程序api实现promise封装过程解析
2019/11/21 Javascript
vue 组件销毁并重置的实现
2020/01/13 Javascript
[51:05]DOTA2上海特级锦标赛主赛事日 - 5 败者组决赛Liquid VS EG第一局
2016/03/06 DOTA
Pyramid Mako模板引入helper对象的步骤方法
2013/11/27 Python
python多线程socket编程之多客户端接入
2017/09/12 Python
Python获取指定文件夹下的文件名的方法
2018/02/06 Python
使用Python监控文件内容变化代码实例
2018/06/04 Python
python文件转为exe文件的方法及用法详解
2019/07/08 Python
在Python中append以及extend返回None的例子
2019/07/20 Python
CSS3制作皮卡丘动画壁纸的示例
2020/11/02 HTML / CSS
性能服装:HYLETE
2018/08/14 全球购物
ANINE BING官方网站:奢华的衣橱基本款和时尚永恒的单品
2019/11/26 全球购物
志愿者爱心公益活动策划方案
2014/09/15 职场文书
行政人事专员岗位职责
2015/04/07 职场文书
2016春季幼儿园开学寄语
2015/12/03 职场文书
导游词之开封禹王台风景区
2019/12/02 职场文书
background-position百分比原理详解
2021/05/08 HTML / CSS
python3实现无权最短路径的方法
2021/05/12 Python
html+css实现滚动到元素位置显示加载动画效果
2021/08/02 HTML / CSS
MySQL优化之慢日志查询
2022/06/10 MySQL