我应该使用观察者模式吗?

时间:2011-04-19 13:43:21

标签: php design-patterns observer-pattern

我有一种情况,我认为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 feed,它存储来自用户的一些列和来自订单的一些列。首次访问提要时,它会从数据库中提取所需信息,并生成xml提要,并将对象存储在memcached中。任何后续的Feed命中都来自memcached。

我想要做的是,如果在用户或订单中更改了某些字段,我想更新memcached密钥。由于我没有存储来自用户的所有字段,或来自订单的所有字段,我不希望它发生在任何save()调用上(同样,xml生成脚本有点数据库密集型)

通过阅读Observer模式,我认为User / Order对象也将实现SplSubject,并在其构造函数中附加XMLObserver。我必须覆盖save()方法以通知任何附加的观察者。如果某些字段被更改,我只会调用notify。 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))来调用静态方法。我并没有真正看到如何使用观察者是有益的,但我可能会以错误的方式解决这个问题。

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

1 个答案:

答案 0 :(得分:0)

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

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

  

观察者模式可让您改变   主题和观察者独立。   您可以重复使用主题而无需重复使用   他们的观察者,反之亦然。它   让你无需添加观察者   修改主题或其他   观察者。

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