【问题标题】:Should I be using the observer pattern?我应该使用观察者模式吗?
【发布时间】: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


【解决方案1】:

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

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

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

还有其他好处,但我认为在您的场景中您不会从中受益太多。

【讨论】:

  • 是的,我原本以为 Observer 是我应该使用的,因为 memcached 会在主题更改时更新,但由于我不能不修改主题,所以我可能不应该使用它。感谢您的帮助!
猜你喜欢
  • 2016-02-02
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-20
  • 2023-04-10
相关资源
最近更新 更多