定义:在对象之间定义一对多依赖,当一个对象改变状态,依赖它的其他对象都会接到通知并自动更新。
文章目录- php23种设计模式-观察者模式(2)
- 观察者模式
- 官方解释
- 白话版
- 生活中场景
- 例子A
- 业务场景
- 未来拓展
- 实现思路
- 代码实现
- 观察者模式的组成
- 观察者模式的组成部分可分为以下4块:
- 观察者模式的使用原理
- 如果不使用设计模式会产生那些后果
- 总结
观察者模式 官方解释
在对象之间创建一对多依赖,当一个对象改变状态,依赖它的其他对象都会收到通知并自动更新。白话版
一个发布通知者,好多个接收通知者,发布者调用接收者,接收者自己完成更新逻辑。 发布者只负责调用接收者,接受者只负责自己的业务逻辑。生活中场景
报社送报纸: 报社:发布信息着(发布者) 收报纸的客户:接收信息者(订阅者)
例子A 业务场景
现在要开发一款冒险类游戏,要在下个月上线一个新职业“拳击手”,现在产品经理想给玩家发通知,通知形式:短信、邮箱、站内信。未来拓展
产品说:未来可能会新增其他通知形式,比如脸书、推特等实现思路
- 找出业务之间的一对多关系
- 创建一个订阅者名单
- 发布者就按名单通知订阅者,发布者只负责通知,订阅者只负责自己的更新业务逻辑。
-
在上述需求中谁是发布者?游戏平台方。
-
谁是订阅者(观察者)?发布通知的方式(多种通知方式)。
-
发布者需要做什么?负责通知每种方式,你们有任务要执行了。
-
订阅者(观察者)需要做什么?负责将订阅消息告知给每个玩家。
-
于是你得到了它。
- 代码实现
message = $message;
}
//新增观察者
public function registerObserver(Observer $observer){
$this->observer_array[] = $observer;
}
//删除指定观察者
public function deleteObserver(Observer $observer){
$index = array_search($observer,$this->observer_array);
array_splice($this->observer_array,$index,1);
echo '删除成功
';
}
//发送通知给观察者
public function notifyObserver(){
$_arr = $this->observer_array;
foreach ($_arr as $v){
$v->send($this->message);
}
}
}
//观察者接口
interface Observer{
public function send($message);
}
//短信发送
class Note implements Observer {
public function send($message){
echo "执行短信发送:{$message}
";
}
}
//邮件发送
class Mail implements Observer {
public function send($message){
echo "执行邮件发送:{$message}
";
}
}
//站内信发送
class Systematic implements Observer {
public function send($message){
echo "执行站内信发送:{$message}
";
}
}
$obj = new Publisher();//实例化发送者(主题的发布人)
$note = new Note();//实例化观察者(接受消息通知的人)
$mail = new Mail();//实例化观察者(接受消息通知的人)
$systematic = new Systematic();//实例化观察者(接受消息通知的人)
//注册观察者(接受消息的人)
$obj->setMessage('新的“拳击手”职业将在2022年1月31日上线,届时创建该职业者都将获得“拳霸”永久称号');
$obj->registerObserver($note);
$obj->registerObserver($mail);
$obj->registerObserver($systematic);
$obj->notifyObserver();//执行通知发送
这样按照产品要求,未来如果新增推送方式时,直接新增注册观察者、与新的观察者实现类即可。观察者模式的组成 观察者模式的组成部分可分为以下4块:
- 1个发布者接口父类:用来约束通用方法接口统一进行调用(非必要,不按照他的类图省略这一步也是可以的。)
- 1个发布者接口实现子类:用来实现注册、删除观察者,设置观察者列表,实现通知观察者更新方法
- 至少1个观察者接口类:用来约束那些子类中要实现的方法
- 至少1个或多个接口观察者实现类:用来实现观察者接口类中的方法,统一的方法名以及形参格式,方便发布者进行调用及规范维护。
- 只触发一处就可导致连锁反应,只要发布者的通知方法被调用,即可咋方法内部实现多个发送信息方法的调用。
- 发送方法的业务逻辑有自己进行实现
- 该模式的核心思想就是多用组合少用继承,具体体现在组合在“发布者-通知方法”中进行。减少继承,测模式存在一定的耦合。
如果没有使用设计模式也许会这样编码
";
echo "执行邮件发送:{$message}
";
echo "执行站内信发送:{$message}
";
}
}
$obj = new SendMessage;
$message = '最新职业已经上线,欢迎体验!';
$obj->send($message);
这只是echo了结构,实际开发场景中这里的每个‘echo’都将是长长的业务逻辑代码,如果某天产品说,这次的活动不需要“站内信”和"短信功能了,那就要打开源码进行删除代码,某天突然又要加上这2个功能,可能会可麻烦,而且要是新增其他功能后,这个send方法可能会变的更长,更不利于代码的维护。总结 观察者模式的设计原则: 1.少用继承,多用组合,这样使得代码更加灵活 2.封装变化 3.针对接口编程,而不是针对实现编程 4.为交互对象间的松耦合设计而努力,松耦合设计更具有弹性,更能应对变化



