PHP设计模式中观察者模式详解
观察者模式是一种行为型设计模式,它允许对象在状态发生改变时自动通知其它对象。在PHP中,观察者模式通常用于实现事件驱动的编程模型。
观察者模式的实现
观察者模式通常由两个主要组件组成:主题和观察者。主题是一个对象,它维护一组观察者,并在状态发生改变时通知它们。观察者是一个接口,它定义了在主题状态发生改变时需要执行的操作。
以下是观察者模式的实现步骤:
- 定义主题接口
主题接口定义了添加、删除和通知观察者的方法。
interface Subject {
public function attach(Observer $observer);
public function detach(Observer $observer);
public function notify();
}
在这个示例中,我们定义了一个Subject
接口,它包含了attach()
、detach()
和notify()
方法。
- 定义观察者接口
观察者接口了在主题状态发生改变时需要执行的操作。
interface Observer {
public function update(Subject $subject);
}
在这个示例中,我们定义了一个Observer
接口,它包含了update()
方法。
- 实现主题类
主题类实现了主题接口,并维护了一组观察者。
class ConcreteSubject implements Subject {
private $observers = [];
public function attach(Observer $observer) {
$this->observers[] = $observer;
}
public function detach(Observer $observer) {
$index = array_search($observer, $this->observers);
if ($index !== false) {
unset($this->observers[$index]);
}
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
}
在这个示例中,我们实现了一个ConcreteSubject
类,它实现了Subject
接口,并维护了一组观察者。
- 实现观察者类
观察者类实现了观察者接口,并在主题状态发生改变时执行相应的操作。
class ConcreteObserver implements Observer {
public function update(Subject $subject) {
// 在主题状态发生改变时执行相应的操作
}
}
在这个示例中,我们实现了一个ConcreteObserver
,它实现了Observer
接口,并在主题状态发生改变时执行相应的操作。
- 使用观察者模式
使用观察者模式时,需要创建一个主题对象,并向它添加一组观察者。当主题状态发生改变时,调用主题对象的notify()
方法通知观察者。
以下是使用观察者模式的示例:
// 创建主题对象
$subject = new ConcreteSubject();
// 创建观察者对象
$observer1 = new ConcreteObserver();
$observer2 = new ConcreteObserver();
// 向主题对象添加观察者
$subject->attach($observer1);
$subject->attach($observer2);
// 当主题状态发生改变时,通知观察者
$subject->notify();
在这个示例中,我们创建了一个主题对象和两个观察者对象,并向主题对象添加了这两个观察者。当主题状态发生改变时,调用主题对象的notify()
方法通知观察者。
示例1:使用观察者模式实现事件监听器
以下是使用观察者模式实现事件监听器的示例:
// 定义主题接口
interface EventSubject {
public function attach(EventObserver $observer);
public function detach(EventObserver $observer);
public function notify($event);
}
// 定义观察者接口
interface EventObserver {
public function handle($event);
}
// 实现主题类
class Event implements EventSubject {
private $observers = [];
public function attach(EventObserver $observer) {
$this->observers[] = $observer;
}
public function detach(EventObserver $observer) {
$index = array_search($observer, $this->observers);
if ($index !== false) {
unset($this->observers[$index]);
}
}
public function notify($event) {
foreach ($this->observers as $observer) {
$observer->handle($event);
}
}
}
// 实现观察者类
class LogObserver implements EventObserver {
public function handle($event) {
// 记录事件日志
}
}
// 使用观察者模式
$event = new Event();
$event->attach(new LogObserver());
$event->notify('event occurred');
在这个示例中,我们使用观察者模式实现了一个事件监听器。当事件发生时,调用主题对象的notify()
方法通知观察者。
示例2:使用观察者模式实现MVC模式
以下是使用观察者模式实现MVC模式的示例:
// 定义主题接口
interface ModelSubject {
public function attach(ModelObserver $observer);
public function detach(ModelObserver $observer);
public function notify();
}
// 定义观察者接口
interface ModelObserver {
public function update(ModelSubject $subject);
}
// 实现主题类
class Model implements ModelSubject {
private $observers = [];
private $data = [];
public function attach(ModelObserver $observer) {
$this->observers[] = $observer;
}
public function detach(ModelObserver $observer) {
$index = array_search($observer, $this->observers);
if ($index !== false) {
unset($this->observers[$index]);
}
}
public function notify() {
foreach ($this->observers as $observer) {
$observer->update($this);
}
}
public function setData($data) {
$this->data = $data;
$this->notify();
}
public function getData() {
return $this->data;
}
}
// 实现观察者类
class View implements ModelObserver {
public function update(ModelSubject $subject) {
$data = $subject->getData();
// 更新视图
}
}
// 使用观察者模式
$model = new Model();
$view = new View();
$model->attach($view);
$model->setData(['foo' => 'bar']);
在这个示例中,我们使用观察者模式实现了MVC模式。当模型数据发生改变时,调用主题对象的notify()
方法通知观察者更新视图。