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 相关文章推荐
php递归创建和删除文件夹的代码小结
Apr 13 PHP
PHP中最容易忘记的一些知识点总结
Apr 28 PHP
编写php应用程序实现摘要式身份验证的方法详解
Jun 08 PHP
php ctype函数中文翻译和示例
Mar 21 PHP
php实现的支持imagemagick及gd库两种处理的缩略图生成类
Sep 23 PHP
Linux下安装PHP MSSQL扩展教程
Oct 24 PHP
php中解析带中文字符的url函数分享
Jan 20 PHP
php使用指定字符列表生成随机字符串的方法
Apr 18 PHP
php中memcache 基本操作实例
May 17 PHP
PHP利用APC模块实现大文件上传进度条的方法
Oct 29 PHP
php  单例模式详细介绍及实现源码
Nov 05 PHP
Laravel 集成微信用户登录和绑定的实现
Dec 27 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自动反斜杠的函数代码
2010/01/05 PHP
教你如何快捷的使用cmd访问mysql小技巧
2014/05/26 PHP
PHP模糊查询的实现方法(推荐)
2016/09/06 PHP
利用PHP判断文件是否为图片的方法总结
2017/01/06 PHP
laravel excel 上传文件保存到本地服务器功能
2019/11/14 PHP
javascript判断单选框或复选框是否选中方法集锦
2007/04/04 Javascript
jquery做的一个简单的屏幕锁定提示框
2014/03/26 Javascript
JS+CSS实现下拉列表框美化效果(3款)
2015/08/15 Javascript
JS实现消息来时让网页标题闪动效果的方法
2016/04/20 Javascript
浅谈JavaScript的自动垃圾收集机制
2016/12/15 Javascript
js判断手机系统是android还是ios
2017/03/07 Javascript
微信小程序 template模板详解及实例代码
2017/03/09 Javascript
vue中七牛插件使用的实例代码
2017/07/28 Javascript
获取layer.open弹出层的返回值方法
2018/08/20 Javascript
JavaScript使用递归和循环实现阶乘的实例代码
2018/08/28 Javascript
详解js模板引擎art template数组渲染的方法
2018/10/09 Javascript
node.js爬取中关村的在线电瓶车信息
2018/11/13 Javascript
laydate如何根据开始时间或者结束时间限制范围
2018/11/15 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
vue3.0+vue-router+element-plus初实践
2020/12/02 Vue.js
[48:29]2018DOTA2亚洲邀请赛3月30日 小组赛A组 LGD VS KG
2018/03/31 DOTA
python基础while循环及if判断的实例讲解
2017/08/25 Python
Python基于回溯法子集树模板解决取物搭配问题实例
2017/09/02 Python
NetworkX之Prim算法(实例讲解)
2017/12/22 Python
解决python打不开文件(文件不存在)的问题
2019/02/18 Python
python开启debug模式的方法
2019/06/27 Python
Python编译为二进制so可执行文件实例
2019/12/23 Python
Python 实现敏感目录扫描的示例代码
2020/05/21 Python
python 服务器运行代码报错ModuleNotFoundError的解决办法
2020/09/16 Python
python绘图pyecharts+pandas的使用详解
2020/12/13 Python
一款恶搞头像特效的制作过程 利用css3和jquery
2014/11/21 HTML / CSS
一款基于css3麻将筛子3D翻转特效的实例教程
2014/12/31 HTML / CSS
高二地理教学反思
2014/01/24 职场文书
如何撰写一封出色的求职信
2014/04/27 职场文书
在Python 中将类对象序列化为JSON
2022/04/06 Python
Java版 简易五子棋小游戏
2022/05/04 Java/Android