У меня есть ситуация, когда я думаю, что шаблон 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)
). Я на самом деле не понимаю, как выгодно использовать наблюдателя, но я могу ошибаться.
Кто-нибудь знает лучший способ справиться с этим?