Должен ли я использовать шаблон наблюдателя? - PullRequest
0 голосов
/ 19 апреля 2011

У меня есть ситуация, когда я думаю, что шаблон Observer будет наиболее целесообразным для использования, но я не уверен, что лучший способ реализовать.

Скажем, у меня есть 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 немного интенсивно использует БД)

Читая о шаблоне Observer, я подумал, что объекты User / Order также будут реализовывать 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)). Я на самом деле не понимаю, как выгодно использовать наблюдателя, но я могу ошибаться.

Кто-нибудь знает лучший способ справиться с этим?

1 Ответ

0 голосов
/ 19 апреля 2011

Исходя из наших комментариев, возможно, вам следует подумать о написании функции, которая определяет, следует ли распространять изменение в memcache (в зависимости от полей, которые были изменены), вместо того, чтобы использовать шаблон наблюдателя.

Поскольку memcache будет вашим единственным подписчиком, на который нужно всегда подписываться, я не думаю, что вы сильно выиграете от преимуществ этого шаблона. От http://www.research.ibm.com/designpatterns/example.htm:

Шаблон Observer позволяет варьировать предметы и наблюдатели самостоятельно. Вы можете повторно использовать предметы без повторного использования их наблюдатели и наоборот. Это позволяет добавлять наблюдателей без изменение предмета или другого наблюдателей.

Существуют и другие преимущества, но я не думаю, что вы бы выиграли от них в вашем сценарии.

...