Стандартная библиотека PHP включает то, что некоторые ресурсы называют ссылочной реализацией шаблона Observer, с помощью SplSubject
и SplObserver
. В моей жизни я не могу понять, насколько они очень полезны без возможности передачи фактических событий или любой другой информации вместе с уведомлениями:
class MySubject implements SplSubject {
protected $_observers = [];
public function attach(SplObserver $observer) {
$id = spl_object_hash($observer);
$this->_observers[$id] = $observer;
}
public function detach(SplObserver $observer) {
$id = spl_object_hash($observer);
if (isset($this->_observers[$id])) {
unset($this->_observers[$id]);
}
}
public function notify() {
foreach ($this->_observers as $observer) {
$observer->update($this);
}
}
}
class MyObserver implements SplObserver {
public function update(SplSubject $subject) {
// something happened with $subject, but what
// was it???
}
}
$subject = new MySubject();
$observer = new MyObserver();
$subject->attach($observer);
$subject->notify();
Похоже, что эти интерфейсы практически бесполезны для любой реальной проблемы. Может кто-нибудь просветить меня?
Edit:
Вот моя самая большая проблема с интерфейсом (хотя есть и другие):
public function update(SplSubject $subject, Event $event) { /* ... */ }
... устанавливает следующую фатальную ошибку:
PHP Fatal error: Declaration of MyObserver::update() must be compatible with SplObserver::update(SplSubject $SplSubject)
Изменить # 2:
Предоставление дополнительных параметров по умолчанию, задавая их значения по умолчанию, предотвращает фатальную ошибку и обеспечивает способ передачи контекста, что делает реализации целесообразными. Я раньше не знал об этом, так что это в значительной степени отвечает на мой вопрос. Решение состоит в том, чтобы передать ваши собственные данные о событии/сообщении и проверить его существование внутри SplObserver::update()
.