> **设计模式-观察者模式**
## 说明 ##
**观察者模式(Observer),当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新。**
----------
##模式说明##
场景:一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新的逻辑增多之后,代码会变得难以维护.这种方式是耦合的,侵入式的,增加新的逻辑需要改变事件主题的代码
观察者模式实现了低耦合,非侵入式的通知与更新机制
在PHP5.1之后,PHP提供了SPL(标准PHP库 - Standard PHP Library)这个库,这个库包括一组解决标准问题的接口和类其中就有观察者接口。
观察者模式的核心在于Subject和Observer 接口。Subject包含一个给定的状态,观察者"订阅"这个主题,将主题的当前状态通知观察者。可以认为它是一个博客,有很多订阅者,会定期地为订阅或定期阅读博客的各类用户更新一组信息。每次博客发生改变时(其状态改变),所有订阅者"都会得到通知"。
![请输入图片描述][1]
SplSubject {
/* 方法 */
abstract public attach ( SplObserver $observer ) : void //附加SplObserver观察者
abstract public detach ( SplObserver $observer ) : void //分离SplObserver观察者
abstract public notify ( void ) : void //通知SplObserver观察者
}
SplObserver {
/* 方法 */
abstract public update ( SplSubject $subject ) : void //接收被观察者更新
}
##示例代码##
<h5>场景说明</h5>
新用户注册之后,对新用户进行 初始话密码 和 发送短信接口操作
<h5>被观察者User类</h5>
//被观察者,用户注册之后 1.初始话密码 2.发送短信接口
//被观察者类必须实现SplSubject接口 且实现接口的 attach() detach() notify()方法
class User implements SplSubject {
public $userName;
public $phone;
public $observers; //用来存储观察者对象
public function __construct($userName,$phone)
{
$this->userName=$userName;
$this->phone=$phone;
$this->observers = new SplObjectStorage();//SplObjectStorage是SPL标准库中的数据结构对象容器,用来存储观察者对象
}
/**
* @param SplObserver $observer
* 添加观察者
*/
public function attach(SplObserver $observer)
{
// TODO: Implement attach() method.
$this->observers->attach($observer);
}
/**
* @param SplObserver $observer
* 移除观察者
*/
public function detach(SplObserver $observer)
{
// TODO: Implement detach() method.
$this->observers->detach($observer);
}
/**
* 执行观察者操作
*/
public function notify()
{
foreach ($this->observers as $observer) {
$observer->update($this);
}
// TODO: Implement notify() method.
}
//新用户注册流程 ,注册成功执行notify方法
public function register(){
//if(success)
$this->notify();
}
}
<h5>观察者类</h5>
观察者UserInit类和SendMessage类
//观察者 用户初始化类用来实现用户注册后的初始密码等操作
//观察者类必须实现SplObserver接口,并实现update() 方法
class UserInit implements SplObserver {
/**
* @param SplSubject $subject
*/
public function update(SplSubject $subject)
{
echo "用户".$subject->userName."的初始密码为:".mt_rand(100000, 999999).PHP_EOL;
// TODO: Implement update() method.
}
}
//观察者 发送短信类用来实现用户注册后的将用用户的信息发送给用户
//观察者类必须实现SplObserver接口,并实现update() 方法
class SendMessage implements SplObserver {
/**
* @param SplSubject $subject
*/
public function update(SplSubject $subject)
{
echo "已经向用户".$subject->userName."手机号".$subject->phone."发送短信".PHP_EOL;
// TODO: Implement update() method.
}
}
<h5>测试</h5>
header('Content-Type: text/plain');
$user=new User("zhangsan","17600128056");
$user->attach(new UserInit());
$user->attach(new SendMessage());
//用户
$user->register();
<h5>结果</h5>
浏览器输出结果:
用户zhangsan的初始密码为:620834
已经向用户zhangsan手机号17600128056发送短信
## 结尾 ##
<p style="background-image: -webkit-linear-gradient(left, #3498db, #f47920 10%, #d71345 20%, #f7acbc 30%,#ffd400 40%, #3498db 50%, #f47920 60%, #d71345 70%, #f7acbc 80%, #ffd400 90%, #3498db);color: transparent;-webkit-text-fill-color: transparent;-webkit-background-clip: text;text-align:center;">
心如花木,向阳而生。
</p>
[1]: https://blog.zxliu.cn/usr/uploads/2020/11/2353528746.png
[2]: https://blog.zxliu.cn/usr/uploads/2020/11/1966401635.png