热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php观察者模式怎么用,PHP设计模式——观察者模式

前言知识就是作为观察者所获得的结论,经过科学培训的观察者会为我们提供所有能感知的现实。设计观察者模式是为了让一个对象跟踪某个状态,知道状态何时改变&#x

前言

知识就是作为观察者所获得的结论,经过科学培训的观察者会为我们提供所有能感知的现实。设计观察者模式是为了让一个对象跟踪某个状态,知道状态何时改变,一旦状态改变,所有订阅对象都能得到通知。如果需要保证一个状态的一致性(比如说:状态触发类的应用),但是这个给定状态可能有多个不同的用户等级,这种情况下观察者模式就很适用,而且很有帮助,各司其职。利用观察者模式可以维护一致性,同时记录创建一个给定的状态的对象个数。

观察者模式很直观。何必让多个对象创建或跟踪一个给定的状态呢?如果由一个对象完成这个工作,然后通知其他可能用到这个状态的对象,这样会合理得多。

使用SPL实现观察者模式

1、可用于观察者设计模式的3个SPL接口/类如下:

● SplSubject

● SplObserver

● SplObjectStorage

1.1、SplSubject

namespace common\observer;

use Yii;

/**

* SplSubject.

*

*/

interface SplSubject

{

/*SplSubject 接口*/

public function attach (SplObserver $observer);

public function detach (SplObserver $observer);

public function notify ();

}

注意这个SplSubject 接口指定attach()和detach()方法参数中$observer的数据类型必须是一个SplObserver 对象。

1.2、SplObserver

SplObserver 接口只有一个update()方法,如下所示:

namespace common\observer;

use Yii;

/**

* SplObserver

*

*/

interface SplObserver

{

/*更新方法*/

public function update (SplSubject $subject);

}

update()方法对于观察者模式至关重要,因为它会得到Subject状态的最新变化,并交给观察者实例。

1.3、SplObjectStorage

SplObjectStorage 类与观察者设计模式没有内在的关系,不过通过它其内置的attach()和detach()方法可以很方便的将观察者实例与一个主题实例相关联以及解除关联。

namespace common\observer;

use Yii;

/**

* SplObjectStorage 存储对象的类

*

* @property string $storage 存储对象

*

*/

class SplObjectStorage

{

public $storage;

//增加方法

public function attach(SplObserver $observer)

{

$this->storage[] = $observer;

}

//删除方法

public function detach(SplObserver $observer)

{

if(is_int($idx = array_search($observer, $this->storage)))

{

unset($this->storage[$idx]);

}

}

}

注释:如果直接用PHP类库的SplObjectStorage类的话,1.3可以不看了,只需要把1.4里面的$this->observers = new SplObjectStorage();修改为$this->observers = new \SplObjectStorage();(原因可以去了下PHP的解命名空间和文件加载机制。参考资料),notify方法里的$this->observers->storage修改为$this->observers即可。

1.4、SPL具体主题

SplSubject接口不包括获取方法和设置方法,不过这也是观察者设计模式中的一部分,所以需要增加获取方法和设置方法。设置方法setData()包含一个参数,这是要增加的任何类型的数据。获取方法getData()存储当前的主题状态,由具体观察者用来更新观察者数据。

另外还增加了setObservers()方法。并不是在构造函数中设置SplObjectStorage()实例,也没有在setData()方法中设置观察者实例,这里实现了一个单独的setObservers()方法,可以提供更轻松的耦合,并允许有多组观察者。

namespace common\observer;

use Yii;

//ConcreteSubject

class ConcreteSubject implements SplSubject

{

private $observers,$data;

public function setObservers()

{

//sqlObjectStorage 专门用来存储对象的类

$this->observers = new SplObjectStorage();

}

//添加观察者

public function attach(SplObserver $observer)

{

$this->observers->attach($observer);

}

//剔除观察者

public function detach(SplObserver $observer)

{

$this->observers->detach($observer);

}

//通知notify

public function notify()

{

foreach ($this->observers->storage as $key =>$observer) {

$observer->update($this);

}

}

//设置方法

public function setData($dataNow)

{

$this->data=$dataNow;

}

//获取方法

public function getData()

{

return $this->data;

}

}

?>

1.5、SPL具体观察者

用于实现更新函数来更新关联的观察者实例。

namespace common\observer;

use Yii;

//ConcreteObserver

class ConcreteObserver implements SplObserver

{

public function update(SplSubject $subject)

{

echo $subject->getData()."";

}

}

?>

(附加的普通用户具体观察者)

namespace common\observer;

use Yii;

//Userbservers

class UserObserver implements SplObserver

{

public function update(SplSubject $subject)

{

echo '我是普通用户,请给我对应的普通用户服务';

}

}

?>

1.6、SPL客户

“SPL”Client 类只是一个标准客户。这个客户按照SPL接口向具体主题和观察者发出多个请求,不过自己并没有实现SPL类和接口。

namespace common\observer;

use Yii;

//Client

class Client

{

public function __construct()

{

echo "

创造新的具体观察者,新的具体主体:

";

$ob1 = new ConcreteObserver();

$ob2 = new ConcreteObserver();

$ob3 = new ConcreteObserver();

$Subject = new ConcreteSubject();

$Subject->setObservers();

$Subject->setData("这是你的数据!");

$Subject->attach($ob1);

$Subject->attach($ob2);

$Subject->attach($ob3);

$Subject->notify();

echo "

删除ob3,结果是ob1和ob2的通知:

";

$Subject->detach($ob3);

$Subject->notify();

echo "

剩余的数据和附加数据还有删除ob2,结果是ob1和ob3的通知:

";

$Subject->setData("更多的数据,只有ob1和ob3是需要的");

$Subject->attach($ob3);

$Subject->detach($ob2);

$Subject->notify();

echo "

剩余数据和附加新数据,结果是ob1和ob3还有“新数据”的通知:

";

$Subject->attach(new \common\observer\UserObserver);

$Subject->notify();

}

}

?>

1.7、Client的调用输出如下:

调用:$worker=new commonobserverClient();

输出:

bVIgCb?w=651&h=419

总结分析

这里SplObjectStorage类是我自己写的,贴出来分享一下。PHP5.1.0以及更高的版本有很多特性,其中之一就是提供了一组可以用于观察者的设计模式的接口。可以研究一下怎么使用,SplObserver接口以及SplSubject和SplObjectStorage接口,利用这些接口,构建观察者模式简直易如反掌。“SPL”是标准PHP类库(Standard PHP Library)的简写,这个库中包括一组解决标准问题的接口和类。参考手册

相关资料



推荐阅读
  • MySQL 5.7 学习指南:SQLyog 中的主键、列属性和数据类型
    本文介绍了 MySQL 5.7 中主键(Primary Key)和自增(Auto-Increment)的概念,以及如何在 SQLyog 中设置这些属性。同时,还探讨了数据类型的分类和选择,以及列属性的设置方法。 ... [详细]
  • 深入探索HTTP协议的学习与实践
    在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
  • 深入解析C#中app.config文件的配置与修改方法
    在C#开发过程中,经常需要对系统的配置文件进行读写操作,如系统初始化参数的修改或运行时参数的更新。本文将详细介绍如何在C#中正确配置和修改app.config文件,包括其结构、常见用法以及最佳实践。此外,还将探讨exe.config文件的生成机制及其在不同环境下的应用,帮助开发者更好地管理和维护应用程序的配置信息。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • 作为软件工程专业的学生,我深知课堂上教师讲解速度之快,很多时候需要课后自行消化和巩固。因此,撰写这篇Java Web开发入门教程,旨在帮助初学者更好地理解和掌握基础知识。通过详细记录学习过程,希望能为更多像我一样在基础方面还有待提升的学员提供有益的参考。 ... [详细]
  • 在Linux系统中,为了提高安全性,可以通过设置命令执行超时和用户超时注销来防止因用户长时间未操作而带来的安全隐患。具体而言,可以通过编辑 `/etc/profile` 文件,添加或修改相关参数,确保用户在指定时间内无操作后自动注销。此外,还可以利用 `timeout` 命令来限制特定命令的执行时间,进一步增强系统的稳定性和安全性。 ... [详细]
  • Hadoop的文件操作位于包org.apache.hadoop.fs里面,能够进行新建、删除、修改等操作。比较重要的几个类:(1)Configurati ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 在本文中,我们将详细介绍如何构建一个用于自动回复消息的XML类。当微信服务器接收到用户消息时,该类将生成相应的自动回复消息。以下是具体的代码实现:```phpclass We_Xml { // 代码内容}```通过这个类,开发者可以轻松地处理各种消息类型,并实现高效的自动回复功能。我们将深入探讨类的各个方法和属性,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在将Excel数据导入MySQL数据库的过程中,如何确保不会生成重复记录?本文介绍了一种方法,通过PHP脚本检查数据库中是否存在相同的“Code”字段值,从而避免重复记录的产生。该方法不仅提高了数据导入的准确性,还增强了系统的健壮性。 ... [详细]
  • 本文详细介绍了在C#编程环境中绘制正方形图像的技术和实现方法,通过具体示例代码帮助读者理解和掌握相关技巧。内容涵盖从基础概念到实际应用的各个方面,适合初学者和有一定经验的开发者参考。希望对您的C#学习之旅有所帮助,并激发您进一步探索的兴趣。 ... [详细]
  • 本文详细探讨了MySQL数据库实例化参数的优化方法及其在实例查询中的应用。通过具体的源代码示例,介绍了如何高效地配置和查询MySQL实例,为开发者提供了有价值的参考和实践指导。 ... [详细]
  • 2018年9月21日,Destoon官方发布了安全更新,修复了一个由用户“索马里的海贼”报告的前端GETShell漏洞。该漏洞存在于20180827版本的某CMS中,攻击者可以通过构造特定的HTTP请求,利用该漏洞在服务器上执行任意代码,从而获得对系统的控制权。此次更新建议所有用户尽快升级至最新版本,以确保系统的安全性。 ... [详细]
  • 本文详细介绍了 PHP 中 `sprintf` 函数的使用方法,并通过具体示例进行说明。例如,使用 `%%` 作为参数时,`%%` 会被替换为 `%`。通过 `echo sprintf($str)` 可以验证这一行为,返回的结果是“测试一下 % 这个参数,会被替换成什么”。此外,文章还探讨了 `sprintf` 函数在格式化字符串中的多种应用场景,包括数字格式化、日期时间处理等,帮助读者全面掌握该函数的使用技巧。 ... [详细]
author-avatar
屁儿最爱李佑晨
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有