2011-04-19 64 views
0

我有一种情况,我认为Observer pattern最适合使用,但我不确定实施的最佳方式。我应该使用观察者模式吗?

说我有2个表

User 
    id 
    name 
    email 
    ... 
Order 
    id 
    user_id 
    total 
    ... 

,其从ORM延伸两者都类,父类具有保存()方法

class User extends ORM { } 

$user = new User(1); 
$user->name = 'New Name' 
$user->save();

我也有一个xml feed,它存储用户的一些列和来自订单的一些列。当第一次访问feed时,它会从数据库中提取所需的信息,并生成一个xml feed,并将这些对象存储在memcached中。任何后续的提要命中都会从memcached中提取。

我想要做的是,如果某些字段以用户或顺序更改,我想更新memcached密钥。由于我没有存储所有来自用户的字段或所有来自订单的字段,我不希望它发生在任何save()调用(也是,xml生成脚本有点db密集)

从阅读关于观察者模式,我在想用户/订单对象也会实现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))。我真的没有看到如何使用观察员是有益的,但我可能会以这种错误的方式去做。

任何人都知道处理此问题的最佳方法?

+0

我不知道我完全理解你的问题,但memcache真的是你唯一的观察者,还是memcache中有多个观察者?有没有这种XML Feed的各种实例,或者只有当其中的字段发生更改时才需要进行更新? – KTF 2011-04-19 13:54:51

+0

目前没有其他观察者设置,所以如果我实现了这一点,memcache将是我唯一的观察者。这也是notify()调用中的一个错误。我需要在save()之后调用notify(),但是我不能访问$ this-> changed,因为在保存 – poops 2011-04-19 14:01:09

+0

之后,它会被清除,只有这个xml feed的实例才会更新,对于每个用户对象 – poops 2011-04-19 14:01:49

回答

0

根据我们的评论,也许你应该考虑编写一个函数,确定是否应该将更改传播到memcache(取决于被更改的字段),而不是使用观察者模式。

由于memcache将是您唯一的订阅者,需要始终订阅,我不认为您会从这种模式的好处中受益匪浅。来自http://www.research.ibm.com/designpatterns/example.htm

观察者模式可以让您独立地更改 主题和观察者。 您可以重复使用主题,而不用重复使用其观察者,反之亦然。它 可让您添加观察者,而不需要修改观察者或其他 观察员。

还有其他的好处,但我不认为你会从你的场景中得到很多好处。

+0

是的,我原本以为观察者是我应该使用的,因为memcached会在主体改变时更新,但由于我不能修改主题,所以我可能不应该使用它。谢谢您的帮助! – poops 2011-04-19 14:28:48

+0

很高兴为您提供帮助。 :) – KTF 2011-04-19 15:25:00