php 设计模式之观察者模式

实例

没用设计模式的代码,这样的代码要是把最上面那部分也要符合要求加进来,就要修改代码,不符合宁增不改的原则

介绍

观察者模式定义对象的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知自动更新!

所有的观察者(observer)全部被注册(register函数)进入数组(事件的_observers[]数组),这样,当事件(例子中是paper)有变化的时候,就能通过遍历(代码19行)来通知所有的观察者。每个观察者再做他们自己对应的更新(代码20行)。

设计原则

 
在观察者模式中,会改变的是主题的状态以及观察者的数目。用这个模式,你可以改变依赖于主题状态的对象,却不必改变主题。——找出程序中会变化的方面,然后将其和固定不变的方面相分离!
 
 主题和观察者都使用接口:观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者。这样可以让两者之间运作正常,又同时具有松耦合的优点! ——针对接口编程,不针对实现编程!
 观察者模式利用“组合”将许多观察者组合进主题中。对象(观察者——主题)之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。 ——多用组合,少用继承!

代码

 <?php
/**
* 观察者模式
* @author: Mac
* @date: 2012/02/22
*/ class Paper{ /* 主题 */
private $_observers = array(); public function register($sub){ /* 注册观察者 */
$this->_observers[] = $sub;
} public function trigger(){ /* 外部统一访问 */
if(!empty($this->_observers)){
foreach($this->_observers as $observer){
$observer->update();
}
}
}
} /**
* 观察者要实现的接口
*/
interface Observerable{
public function update();
} class Subscriber implements Observerable{
public function update(){
echo "Callback\n";
}
}

下面是测试代码

 /*  测试    */
$paper = new Paper();
$paper->register(new Subscriber());
//$paper->register(new Subscriber1());
//$paper->register(new Subscriber2());
$paper->trigger();

总结

       
当新对象要填入的时候,只需要在主题(又叫可观察者)中进行注册(注册方式很多,你也可以在构造的时候,或者框架访问的接口中进行注册),然后实现代码直接在新对象的接口中进行。这降低了主题对象和观察者对象的耦合度。
 
好的设计模式不会直接进入你的代码中,而是进入你的大脑中。

另一份代码

 /**
* 事件产生类
* Class EventGenerator
*/
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();

php 设计模式之观察者模式(订阅者模式)的更多相关文章

  1. Java里观察者模式(订阅发布模式)

    创建主题(Subject)接口 创建订阅者(Observer)接口 实现主题 实现观察者 测试 总结 在公司开发项目,如果碰到一些在特定条件下触发某些逻辑操作的功能的实现基本上都是用的定时器 比如用户 ...

  2. 学习javascript设计模式之发布-订阅(观察者)模式

    1.发布-订阅模式又叫观察者模式,它定义对象之间一种一对多的依赖关系. 2.如何实现发布-订阅模式 2-1.首先指定好发布者 2-2.给发布者添加一个缓冲列表,用户存放回调函数以便通知订阅者 2-3. ...

  3. JS 设计模式八 -- 发布订阅者模式

    概念 发布---订阅模式又叫观察者模式,它定义了对象间的一种一对多(一个发布,多个观察)的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 优点 1 ...

  4. AngularJS的简单订阅发布模式例子

    控制器之间的交互方式广播 broadcast, 发射 emit 事件 类似于 js中的事件 , 可以自己定义事件 向上传递直到 document 在AngularJs中 向上传递直到 rootScop ...

  5. [转] JavaScript设计模式之发布-订阅模式(观察者模式)-Part1

    <JavaScript设计模式与开发实践>读书笔记. 发布-订阅模式又叫观察者模式,它定义了对象之间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖它的对象都将得到通知. 例如 ...

  6. [JS设计模式]:观察者模式(即发布-订阅者模式)(4)

    简介 观察者模式又叫发布---订阅模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 举一个现实生活中的例子,例如小 ...

  7. NET设计模式 第二部分 行为型模式(18):观察者模式(Observer Pattern)

    概述 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系” ——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知.如果这样的依赖关系过于紧密,将使软件不能很好地抵御 ...

  8. JavaScript设计模式(发布订阅模式)

    发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在JavaScript开发中,我们一般用事件模型来替代传统的发布—订阅模式 ...

  9. js - 观察者模式与订阅发布模式

    零.序言 转载&参考: 1.JavaScript 设计模式系列 - 观察者模式 2.JavaScript 设计模式(六):观察者模式与发布订阅模式 一.观察者模式(observer) 概要: ...

随机推荐

  1. 又一个设计工具 Framer X Preview

    又一个设计工具 Framer X Preview 所说比 Sketch 和 Figma 都要好用,不知道是不是真的 ~~ To give you a little background, I've b ...

  2. 洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)

    题目描述 设d(x)为x的约数个数,给定N.M,求 \sum^N_{i=1}\sum^M_{j=1}d(ij)∑i=1N​∑j=1M​d(ij) 输入输出格式 输入格式: 输入文件包含多组测试数据.第 ...

  3. [OS][ linux ] 建立新帳號, 變更密碼, 加入 sudoer

    新增 linux , 設定預設 password, 新增 user 到 sudoers 1. 新增 User sudo useradd aa97 2. 設定 User password sudo pa ...

  4. 转载:【学习之家】Python中__init__.py文件的作用

    Python中__init__.py文件的作用详解 Python中__init__.py文件的作用详解 来源:学习之家 作者:xuexi110 人气:357 发布时间:2016-09-29 摘要:__ ...

  5. php基础-------preg_replace()与preg_replace_callback()

    1.preg_replace() 执行一个正则表达式的搜索和替换. 语法: mixed preg_replace ( mixed $pattern , mixed $replacement , mix ...

  6. POSIX Threads

    POSIX Threads, usually referred to as pthreads, is an execution model that exists independently from ...

  7. hdu 1072 广搜(逃离爆炸迷宫)

    题意: 在n×m的地图上,0表示墙,1表示空地,2表示人,3表示目的地,4表示有定时炸弹重启器.定时炸弹的时间是6,人走一步所需要的时间是1.每次可以上.下.左.右移动一格.当人走到4时如果炸弹的时间 ...

  8. 路飞学城Python-Day24(practise)

    本章总结 练习题 什么是C/S架构? C指的是client(客户端软件),S指的是Server(服务端软件)

  9. Hadoop HA 与 Federation

    最近在做Hadoop上应用开发,需要和HA集成,active name node 切换不能影响应用的运行.在研究HA背景的同时,发现HA和Federation 配置中共用了nameservices 的 ...

  10. js 正则表达式 整合

    正则表达式:断言 取字符串区间: /(?<=["+ star +"]).*(?=["+ end +"])/ // 简单封装 Vue.prototype.s ...