使用SPL内置接口,实现观察者模式(Observer Pattern)
时间:2006-11-15
来源:互联网
观察者模式,引用GoF的话来说:
在《Head First Design Patterns》中,举了一个现实生活中订阅报纸的例子来描述观察者模式:
报社,相当于观察者模式中的Subject,提供订阅/退订报纸。当新报纸出版时,递送(notify)新报纸到已订阅的用户。用户相当于Observer,
可以自由地订阅(attach)/退订(detach)报纸。当某一用户订阅/退订报纸时,不会影响其他用户。
SPL(Standard PHP Library)从PHP 5.1.0新增了对观察者模式的支持,实际也就是新增了2个内置的接口SplObserver、SplSubject:
----------
My Blog: Yimin's Blog
引用:
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖与它的对象都得到通知并被自动更新。报社,相当于观察者模式中的Subject,提供订阅/退订报纸。当新报纸出版时,递送(notify)新报纸到已订阅的用户。用户相当于Observer,
可以自由地订阅(attach)/退订(detach)报纸。当某一用户订阅/退订报纸时,不会影响其他用户。
SPL(Standard PHP Library)从PHP 5.1.0新增了对观察者模式的支持,实际也就是新增了2个内置的接口SplObserver、SplSubject:
复制PHP内容到剪贴板
{
function update(SplSubject $subject);
}
interface SplSubject
{
function attach(SplObserver $observer);
function detach(SplObserver $observer);
function notify();
}
在IBM的《五种常见的PHP设计模式》中也讲到了观察者模式,我现使用SPL内置的接口,改写了其例子:
PHP代码:
interface SplObserver{
function update(SplSubject $subject);
}
interface SplSubject
{
function attach(SplObserver $observer);
function detach(SplObserver $observer);
function notify();
}
复制PHP内容到剪贴板
<?php
class UserList implements SplSubject
{
// 观察者们
private $_observers = array();
// 用户们
private $_list = array();
// 绑定一个观察者
public function attach(SplObserver $observer)
{
$this->_observers []= $observer;
}
// 解除一个观察者
public function detach(SplObserver $observer)
{
foreach ($this->_observers as $id=>$obs)
{
if($obs === $observer)
{
unset($this->_observers[$id]);
}
}
}
// 通知观察者
public function notify()
{
foreach ($this->_observers as $observer)
{
$observer->update($this);
}
}
//新增用户
public function addUser($name)
{
$this->_list[] = $name;
$this->notify();
}
// 获取新增用户
public function getLatestUser()
{
$user = end($this->_list);
reset($this->_list);
return $user;
}
}
class UserListLogger implements SplObserver
{
public function update(SplSubject $subject)
{
$this->log($subject->getLatestUser());
}
public function log($name)
{
echo date('H:i:s') . ', 新增用户' . $name . '<br />';
}
}
$userList = new UserList();
// 绑定一个观察者:日志记录员
$logger = new UserListLogger();
$userList->attach($logger);
$userList->addUser('Yimin');
//休息2秒
sleep(2);
$userList->addUser('Bantu');
?>
当有新用户增加时,UserList的notify()被调用,notyify()通知所有的观察者,也就是调用了观察者的update方法。在UserListLogger的update方法中,采用的是一种"pull"的方式来获取UserList中的数据(getLatestUser())。PHP代码:
<?php
class UserList implements SplSubject
{
// 观察者们
private $_observers = array();
// 用户们
private $_list = array();
// 绑定一个观察者
public function attach(SplObserver $observer)
{
$this->_observers []= $observer;
}
// 解除一个观察者
public function detach(SplObserver $observer)
{
foreach ($this->_observers as $id=>$obs)
{
if($obs === $observer)
{
unset($this->_observers[$id]);
}
}
}
// 通知观察者
public function notify()
{
foreach ($this->_observers as $observer)
{
$observer->update($this);
}
}
//新增用户
public function addUser($name)
{
$this->_list[] = $name;
$this->notify();
}
// 获取新增用户
public function getLatestUser()
{
$user = end($this->_list);
reset($this->_list);
return $user;
}
}
class UserListLogger implements SplObserver
{
public function update(SplSubject $subject)
{
$this->log($subject->getLatestUser());
}
public function log($name)
{
echo date('H:i:s') . ', 新增用户' . $name . '<br />';
}
}
$userList = new UserList();
// 绑定一个观察者:日志记录员
$logger = new UserListLogger();
$userList->attach($logger);
$userList->addUser('Yimin');
//休息2秒
sleep(2);
$userList->addUser('Bantu');
?>
----------
My Blog: Yimin's Blog
作者: Yimin 发布时间: 2006-11-15
支持这种技术文章
作者: 水镜 发布时间: 2006-11-15
引用:
原帖由 水镜 于 2006-11-15 13:54 发表支持这种技术文章
作者: songwl 发布时间: 2006-11-15
这样会不会好一点?
复制PHP内容到剪贴板
<?php
class UserList implements SplSubject
{
// 观察者们
private $_observers = array();
// 用户们
private $_list = array();
// 绑定一个观察者
public function attach(SplObserver $observer)
{
$this->_observers []= $observer;
}
// 解除一个观察者
public function detach(SplObserver $observer)
{
foreach ($this->_observers as $id=>$obs)
{
if($obs === $observer)
{
unset($this->_observers[$id]);
}
}
}
// 通知观察者
public function notify()
{
foreach ($this->_observers as $observer)
{
$observer->update($this);
}
}
//新增用户
public function addUser($name)
{
$this->_list[] = $name;
$this->notify();
}
// 获取新增用户
public function getLatestUser()
{
$user = end($this->_list);
reset($this->_list);
return $user;
}
}
class UserListLogger implements SplObserver
{
public function update(SplSubject $subject)
{
$this->log($subject->getLatestUser());
}
public function log($name)
{
echo '在'.date('H:i:s') . ', 告诉普通用户,新增用户' . $name . '<br />';
}
}
//建立管理员
class AdminListLogger implements SplObserver
{
public function update(SplSubject $subject)
{
$this->log($subject->getLatestUser());
}
public function log($name)
{
echo '在'.date('H:i:s') . ', 告诉亲爱的管理员,新增用户' . $name . '<br />';
}
}
$userList = new UserList();
// 绑定一个观察者:日志记录员
$user = new UserListLogger();
$admin = new AdminListLogger();
$userList->attach($user);
//同时,通知管理员
$userList->attach($admin);
$userList->addUser('Yimin');
//休息2秒
echo '-------------------------<br />';
sleep(2);
$userList->addUser('Bantu');
exit;
?>
PHP代码:
<?php
class UserList implements SplSubject
{
// 观察者们
private $_observers = array();
// 用户们
private $_list = array();
// 绑定一个观察者
public function attach(SplObserver $observer)
{
$this->_observers []= $observer;
}
// 解除一个观察者
public function detach(SplObserver $observer)
{
foreach ($this->_observers as $id=>$obs)
{
if($obs === $observer)
{
unset($this->_observers[$id]);
}
}
}
// 通知观察者
public function notify()
{
foreach ($this->_observers as $observer)
{
$observer->update($this);
}
}
//新增用户
public function addUser($name)
{
$this->_list[] = $name;
$this->notify();
}
// 获取新增用户
public function getLatestUser()
{
$user = end($this->_list);
reset($this->_list);
return $user;
}
}
class UserListLogger implements SplObserver
{
public function update(SplSubject $subject)
{
$this->log($subject->getLatestUser());
}
public function log($name)
{
echo '在'.date('H:i:s') . ', 告诉普通用户,新增用户' . $name . '<br />';
}
}
//建立管理员
class AdminListLogger implements SplObserver
{
public function update(SplSubject $subject)
{
$this->log($subject->getLatestUser());
}
public function log($name)
{
echo '在'.date('H:i:s') . ', 告诉亲爱的管理员,新增用户' . $name . '<br />';
}
}
$userList = new UserList();
// 绑定一个观察者:日志记录员
$user = new UserListLogger();
$admin = new AdminListLogger();
$userList->attach($user);
//同时,通知管理员
$userList->attach($admin);
$userList->addUser('Yimin');
//休息2秒
echo '-------------------------<br />';
sleep(2);
$userList->addUser('Bantu');
exit;
?>
作者: flashjay 发布时间: 2008-03-12
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28