热门标签 | 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)的简写,这个库中包括一组解决标准问题的接口和类。参考手册

相关资料



推荐阅读
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了一个适用于PHP应用快速接入TRX和TRC20数字资产的开发包,该开发包支持使用自有Tron区块链节点的应用场景,也支持基于Tron官方公共API服务的轻量级部署场景。提供的功能包括生成地址、验证地址、查询余额、交易转账、查询最新区块和查询交易信息等。详细信息可参考tron-php的Github地址:https://github.com/Fenguoz/tron-php。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
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社区 版权所有