简单描述
观察者模式(Observer)是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
当对象的状态发生变化时,所有依赖于它的对象都得到通知并被自动更新。它使用的是低耦合的方式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
使用场景
事件
Laravel 中的事件就是实现了观察者模式,Wordpress 的钩子机制
支付场景
支付场景下,用户购买一件商品,当支付成功之后三方会回调自身,在这个时候系统可能会有很多需要执行的逻辑(如:更新订单状态,发送邮件通知,赠送礼品…),这些逻辑之间并没有强耦合,因此天然适合使用观察者模式去实现这些功能,当有更多的操作时,只需要添加新的观察者就能实现,完美实现了对修改关闭,对扩展开放的开闭原则。
订阅功能,例如微博的订阅
当我们订阅了某个人的微博账号,当这个人发布了新的消息,就会通知我们。
实例
PHP 已经定义了 2 个接口用于快速实现观察者模式:SplObserver 和 SplSubject。
下面以订单为例:当状态变化,需要进行相关处理,例如写日志、短信通知。
<?php
// 实现PHP 自带的 SplObserver 抽象接口
class LogObserver implements SplObserver
{
public function update($data)
{
echo 'write log to file.' . "<br>";
}
}
// 实现PHP 自带的 SplObserver 抽象接口
class SmsObserver implements SplObserver
{
public function update($data)
{
echo 'send sms' . "<br>";
}
}
class OrderSubject implements SplSubject
{
public $data;
private $observers = []; //观察者集合
public function attach(SplObserver $observer)
{
array_push($this->observers, $observer);
}
public function detach(SplObserver $observer)
{
return false;
}
public function notify()
{
if(count($this->observers) == 0) return false;
foreach ($this->observers as $observer)
{
$observer->update($this);
}
}
public function change($data)
{
// 假设订单数据正确,这部分的逻辑可以根据真实场景进行随意更改,我这里只是简单示范
if ($data['oid'] == 1 && $data['flag'] == 3)
{
$this->data = $data;
$this->notify();
}
}
}
$order_subject = new OrderSubject();
$order_subject->attach(new LogObserver());//写日志
$order_subject->attach(new SmsObserver());//发短信
$order_subject->change(['oid' => '1', 'flag' => 3]); //订单状态变化,触发观察者
输出结果:
write log to file.
send sms