009-PHP设计模式之观察者模式

九、观察者模式

9.1 什么是观察者模式

观察者模式(Observer Pattern)也叫做发布订阅模式(Publish/subscribe),它是一个在项目中经常使用的模式

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新

9.2 怎么实现观察者模式

Subject 被观察者:定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者;仅仅完成作为被观察者
必须实现的职责:管理观察者并通知观察者

Observer 观察者:观察者接收到消息后,对接收到的信息进行处理

ConcreteSubject 具体的被观察者:定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知

ConcreteObserver 具体的观察者:每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑

<?php
namespace Subject;

interface Observer
{
    public function update();
}

class Observer1 implements Observer
{

    public function update()
    {
        echo "Observer1 receive notify\n";
    }
}

class Observer2 implements Observer
{

    public function update()
    {
        echo "Observer2 receive notify\n";
    }
}

abstract class Subject
{
    private array $obs = [];

    public function add(Observer $observer)
    {
        $key = $observer::class;
        if (isset($this->obs[$key])) {
            echo "observer is exist:{$key}\n";
        } else {
            $this->obs[$observer::class] = $observer;
            echo "observer add success:{$key}\n";
        }
    }

    public function del(Observer $observer)
    {
        $key = $observer::class;
        if (isset($this->obs[$key])) {
            unset($this->obs[$key]);
            echo "remove observer:{$key} \n";
        } else {
            echo "the observer not exist:{$key}\n";
        }
    }

    protected function noticeObserver()
    {
        if (count($this->obs) > 0) {
            foreach ($this->obs as $observer) {
                $observer->update();
            }
        }
    }
}

class ConcreteSubject extends Subject
{
    public function do()
    {
        echo "ConcreteSubject do something\n";
        parent::noticeObserver();
    }
}


$subject = new ConcreteSubject();
$obs1 = new Observer1();
$obs2 = new Observer2();

$subject->add($obs1);
$subject->add($obs2);
$subject->do();
//observer add success:Subject\Observer1
//observer add success:Subject\Observer2
//ConcreteSubject do something
//Observer1 receive notify
//Observer2 receive notify

echo "==============\n";

$subject->del($obs1);
$subject->do();
//remove observer:Subject\Observer1
//ConcreteSubject do something
//Observer2 receive notify

9.3 观察者模式优点是什么

  • 观察者和被观察者之间是抽象耦合:不管是增加观察者还是被观察者都非常容易扩展

9.4 观察者模式缺点是什么

观察者模式需要考虑一下开发效率和运行效率问题,一个被观察者,多个观察者,开发和调试就会比较复杂

一个观察者卡壳,会影响整体的执行效率,所以一般都采用异步

9.5 观察者模式的注意事项

广播链的问题:一个观察者可以有双重身份,既是观察者,也是被观察者,这没什么问题呀,但是链一旦建立,
这个逻辑就比较复杂,可维护性非常差,根据经验建议,在一个观察者模式中最多出现一个对象既是观察者也是被观察者,
也就是说消息最多转发一次(传递两次),这还是比较好控制的

异步处理问题:异步处理就要考虑线程安全和队列的问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值