【发布时间】:2011-04-19 13:43:20
【问题描述】:
我有一种情况,我认为Observer pattern 最适合使用,但我不确定最佳实施方式。
假设我有 2 张桌子
User
id
name
email
...
Order
id
user_id
total
...
两者都是从 ORM 扩展而来的类,并且父类有一个 save() 方法
class User extends ORM { }
$user = new User(1);
$user->name = 'New Name'
$user->save();
我还有一个 xml 提要,它存储一些来自用户的列和一些来自订单的列。首次访问提要时,它会从数据库中提取所需的信息,并生成一个 xml 提要,并将对象存储在 memcached 中。对提要的任何后续命中都从 memcached 中提取。
我想要做的是,如果某些字段在用户或顺序中发生更改,我想更新 memcached 键。因为我没有存储来自用户的所有字段,或者来自订单的所有字段,所以我不希望它发生在任何 save() 调用上(另外,xml 生成脚本有点 db-intensive)
通过阅读观察者模式,我认为用户/订单对象也将实现 SplSubject,并在它们的构造函数中附加一个 XMLObserver。我必须重写 save() 方法来通知任何附加的观察者。如果某些字段被更改,我只会调用通知。 XMLObserver 将更新 memcached。
class User extends ORM implements SplSubject
{
private $observers = array();
function __construct()
{
$this->attach(new XMLObserver);
parent::__construct();
}
function attach(SplObserver $observer)
{
$id = spl_object_hash($observer);
$this->observers[$id] = $observer;
}
function detach(SplObserver $observer)
{
$id = spl_object_hash($observer);
unset($this->observers[$id]);
}
function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
function save()
{
if (in_array($this->changed, array('name')) {
$this->notify();
}
parent::save();
}
}
class XMLObserver implements SplObserver
{
function update(SplSubject $subject)
{
// code here to update memcached key
}
}
我不确定这对我来说是否最有意义。根据我目前的情况,我为什么不根据这些字段是否更改(例如XMLFeed::update($key))调用静态方法。我并没有真正看到使用观察者有什么好处,但我可能会走错路。
有人知道处理这个问题的最佳方法吗?
【问题讨论】:
-
我不确定我是否完全理解您的问题,但内存缓存真的是您唯一的观察者,还是内存缓存中有多个观察者?这个 XML 提要有各种实例,还是只有一个在其中的字段发生变化时总是需要更新?
-
目前没有设置其他观察者,所以如果我实现了这个,memcache 将是我唯一的观察者。 notify() 调用中还有一个错误。我需要在 save() 之后调用 notify(),但我无法访问 $this->changed,因为保存后会被清除
-
对于每个用户对象,也只有一次此 xml 提要的实例要更新
-
对于只有一个应该始终被通知并始终被订阅的观察者来说,这种模式似乎并没有带来太多价值。
标签: php design-patterns observer-pattern