PHP设计模式之观察者模式定义与用法分析


Posted in PHP onApril 04, 2019

本文实例讲述了PHP设计模式之观察者模式定义与用法。分享给大家供大家参考,具体如下:

观察者模式 当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新

场景:当一个事件发生后,要执行一连串更新操作,传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新逻辑增多之后,代码变得难以维护,这种方式是耦合式的,侵入式的,增加新的逻辑需要改变事件主题的代码

观察者模式实现了低耦合,非侵入式的通知与更新

abstract class EventGenerator
{
  private $ObServers = [];
  //增加观察者
  public function add(ObServer $ObServer)
  {
    $this->ObServers[] = $ObServer;
  }
  //事件通知
  public function notify()
  {
    foreach ($this->ObServers as $ObServer) {
      $ObServer->update();
    }
  }
}
/**
 * 观察者接口类
 * Interface ObServer
 */
interface ObServer
{
  public function update($event_info = null);
}
/**
 * 观察者1
 */
class ObServer1 implements ObServer
{
  public function update($event_info = null)
  {
    echo "观察者1 收到执行通知 执行完毕!\n";
  }
}
/**
 * 观察者1
 */
class ObServer2 implements ObServer
{
  public function update($event_info = null)
  {
    echo "观察者2 收到执行通知 执行完毕!\n";
  }
}
/**
 * 事件
 * Class Event
 */
class Event extends EventGenerator
{
  /**
   * 触发事件
   */
  public function trigger()
  {
    //通知观察者
    $this->notify();
  }
}
//创建一个事件
$event = new Event();
//为事件增加旁观者
$event->add(new ObServer1());
$event->add(new ObServer2());
//执行事件 通知旁观者
$event->trigger();

运行结果:

观察者1 收到执行通知 执行完毕!
观察者2 收到执行通知 执行完毕!

1 抽象的事件产生类,定义一个添加观察者方法,和通知方法(执行观察者方法)

2 定义观察者接口,实现方法 ,观察者实现

3 定义具体实现类继承抽象事件,实现通知方法

4 创建对象,增加旁观者,更新

具体注册实例

<?php
 /**
 * 3.1php设计模式-观测者模式
 * 3.1.1概念:其实观察者模式这是一种较为容易去理解的一种模式吧,它是一种事件系统,意味
 *     着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,
 *     观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间
 *     紧密耦合的另一种方法
 * 3.1.2关键点:
 *    1.被观察者->追加观察者;->一处观察者;->满足条件时通知观察者;->观察条件
 *    2.观察者 ->接受观察方法
 * 3.1.3缺点:
 * 3.1.4观察者模式在PHP中的应用场合:在web开发中观察者应用的方面很多
 *    典型的:用户注册(验证邮件,用户信息激活),购物网站下单时邮件/短信通知等
 * 3.1.5php内部的支持
 *    SplSubject 接口,它代表着被观察的对象,
 *    其结构:
 *    interface SplSubject
 *    {
 *      public function attach(SplObserver $observer);
 *      public function detach(SplObserver $observer);
 *      public function notify();
 *    }
 *    SplObserver 接口,它代表着充当观察者的对象,
 *    其结构:
 *    interface SplObserver
 *    {
 *      public function update(SplSubject $subject);
 *    }
 */
 /**
 * 用户登陆-诠释观察者模式
 */
class User implements SplSubject {
  //注册观察者
  public $observers = array();
  //动作类型
  CONST OBSERVER_TYPE_REGISTER = 1;//注册
  CONST OBSERVER_TYPE_EDIT = 2;//编辑
  /**
   * 追加观察者
   * @param SplObserver $observer 观察者
   * @param int $type 观察类型
   */
  public function attach(SplObserver $observer, $type)
  {
    $this->observers[$type][] = $observer;
  }
  /**
   * 去除观察者
   * @param SplObserver $observer 观察者
   * @param int $type 观察类型
   */
  public function detach(SplObserver $observer, $type)
  {
    if($idx = array_search($observer, $this->observers[$type], true))
    {
      unset($this->observers[$type][$idx]);
    }
  }
  /**
   * 满足条件时通知观察者
   * @param int $type 观察类型
   */
  public function notify($type)
  {
    if(!empty($this->observers[$type]))
    {
      foreach($this->observers[$type] as $observer)
      {
        $observer->update($this);
      }
    }
  }
  /**
   * 添加用户
   * @param str $username 用户名
   * @param str $password 密码
   * @param str $email 邮箱
   * @return bool
   */
  public function addUser()
  {
    //执行sql
    //数据库插入成功
    $res = true;
    //调用通知观察者
    $this->notify(self::OBSERVER_TYPE_REGISTER);
    return $res;
  }
  /**
   * 用户信息编辑
   * @param str $username 用户名
   * @param str $password 密码
   * @param str $email 邮箱
   * @return bool
   */
  public function editUser()
  {
    //执行sql
    //数据库更新成功
    $res = true;
    //调用通知观察者
    $this->notify(self::OBSERVER_TYPE_EDIT);
    return $res;
  }
}
/**
* 观察者-发送邮件
*/
class Send_Mail implements SplObserver
{
  /**
   * 相应被观察者的变更信息
   * @param SplSubject $subject
   */
  public function update(SplSubject $subject)
  {
    $this->sendMail($subject->email, $title, $content);
  }
  /**
   *发送邮件
   *@param str $email 邮箱地址
   *@param str $title 邮件标题
   *@param str $content 邮件内容
   */
  public function sendEmail($email, $title, $content)
  {
    //调用邮件接口,发送邮件
  }
}
?>

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

PHP 相关文章推荐
多重?l件?合查?(二)
Oct 09 PHP
在PHP3中实现SESSION的功能(三)
Oct 09 PHP
『PHP』PHP截断函数mb_substr()使用介绍
Apr 22 PHP
php全局变量和类配合使用深刻理解
Jun 05 PHP
解析zend Framework如何自动加载类
Jun 28 PHP
php过滤敏感词的示例
Mar 31 PHP
PHP使用Session遇到的一个Permission denied Notice解决办法
Jul 30 PHP
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
Aug 18 PHP
PHP实现的多彩标签效果代码分享
Aug 21 PHP
php实现简单的语法高亮函数实例分析
Apr 27 PHP
基于php判断客户端类型
Oct 14 PHP
PHP实现基于图的深度优先遍历输出1,2,3...n的全排列功能
Nov 10 PHP
PHP示例演示发送邮件给某个邮箱
Apr 03 #PHP
PHP whois查询类定义与用法示例
Apr 03 #PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
Apr 03 #PHP
PHP反射实际应用示例
Apr 03 #PHP
ThinkPHP3.2.3框架实现执行原生SQL语句的方法示例
Apr 03 #PHP
从ThinkPHP3.2.3过渡到ThinkPHP5.0学习笔记图文详解
Apr 03 #PHP
PHP快速排序算法实现的原理及代码详解
Apr 03 #PHP
You might like
如何使用动态共享对象的模式来安装PHP
2006/10/09 PHP
xml在joomla表单中的应用详解分享
2012/07/19 PHP
PHP通过串口实现发送短信
2015/07/08 PHP
php中10个不同等级压缩优化图片操作示例
2016/11/14 PHP
40款非常棒的jQuery 插件和制作教程(系列一)
2011/10/26 Javascript
一个Action如何调用两个不同的方法
2014/05/22 Javascript
javascript动态修改Li节点值的方法
2015/01/20 Javascript
JQuery中节点遍历方法实例
2015/05/18 Javascript
jQuery实现信息提示框(带有圆角框与动画)效果
2015/08/07 Javascript
javascript类型系统 Window对象学习笔记
2016/01/07 Javascript
老生常谈javascript的类型转换
2016/10/12 Javascript
微信公众号 摇一摇周边功能开发
2016/12/08 Javascript
JavaScript用构造函数如何获取变量的类型名
2016/12/23 Javascript
footer定位页面底部(代码分享)
2017/03/07 Javascript
NodeJS创建最简单的HTTP服务器
2017/05/15 NodeJs
vue 中自定义指令改变data中的值
2017/06/02 Javascript
简述pm2常用命令集合及配置文件说明
2019/05/30 Javascript
JavaScript从原型到原型链深入理解
2019/06/03 Javascript
Python的Django框架中的表单处理示例
2015/07/17 Python
Python设计模式之抽象工厂模式
2016/08/25 Python
Python利用正则表达式实现计算器算法思路解析
2018/04/25 Python
python matplotlib画图库学习绘制常用的图
2019/03/19 Python
如何关掉pycharm中的python console(图解)
2019/10/31 Python
Python timer定时器两种常用方法解析
2020/01/20 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧(自定义信号与槽)详解与实例
2020/03/06 Python
雅诗兰黛(Estee Lauder)英国官方网站:世界顶级化妆品牌
2016/12/29 全球购物
英国大码女性时装零售商:Evans
2018/08/29 全球购物
Java的类与C++的类有什么不同
2014/01/18 面试题
工程专业求职自荐书范文
2014/02/08 职场文书
法律七进实施方案
2014/03/15 职场文书
揭牌仪式策划方案
2014/05/28 职场文书
写自招自荐信的绝招!
2019/04/19 职场文书
python cv2图像质量压缩的算法示例
2021/06/04 Python
Python+OpenCV实现在图像上绘制矩形
2022/03/21 Python
SQL Server2019安装的详细步骤实战记录(亲测可用)
2022/06/10 SQL Server
Vue2项目中对百度地图的封装使用详解
2022/06/16 Vue.js