设计模式 -- 观察者模式

本文介绍了观察者模式,当对象状态改变时,依赖它的对象会收到通知并自动更新,该模式实现了低耦合、非侵入式的通知与更新机制。文中给出了简单代码实现,包括抽象目标、具体目标、抽象观察者和具体观察者等,还通过订单流程举例说明,并探讨了参数传递问题。

基本介绍

1、观察者模式(Observer):当一个对象状态发生改变时,依赖它的对象全部会收到通知,并自动更新

2、场景: 当一个事件发生后,要执行一连串更新操作。传统的编程方式,就是在事件的代码之后直接加入处理逻辑。当更新的逻辑增多之后,代码会变得难以维护。这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件主体的代码。

3、观察者模式实现了低耦合,非侵入式的通知与更新机制。

简单代码实现

(抽象)目标

定义一个观察者集合,并提供方法来增加和删除观察者对象,还包括通知方法

abstract class Subject 
{
    private $observers = [];
    function addObserver(Observer $observer)
    {
        $this->observers[] = $observer;
    }
    
    function notify()
    {
        foreach ($this->observers as $observer) {
            $observer->update();
        }
    }
}

具体目标

class ConcreteSubject extends Subject
{
    function trigger() 
    {
        echo "本身的动作 <br />\n";
    }
}

(抽象)观察者

对观察目标的改变做出反应,只申明更新数据的方法

interface Observer 
{
    function update($event_info = null);
}

具体观察者

观察到目标变化后需要执行的具体动作。可添加到目标类的观察者集合中,或从目标类的观察者集合中删除

具体动作1:

class Observer1 implement Observer
{
    function update($event_info = null) 
    {
        echo "逻辑1 <br />\n";
    }
}

具体动作2:

class Observer2 implement Observer
{
    function update($event_info = null) 
    {
        echo "逻辑2 <br />\n";
    }
}

调用与实现

$event = new Event;
$event->addObserver(new Observer1);
$event->addObserver(new Observer2);
$event->trigger();

扩展

实际情况中,具体观察者类的update()方法在执行时需要使用到具体目标类中的状态或属性。

所以,具体观察者和具体目标类之间有时候还需要存在关联或依赖关系。在具体观察者类中定义一个具体目标实例,通过该实例获取存储在具体目标类中的状态或属性值。

举例

订单流程中,当订单审核拒绝时,除了更新主订单表中的状态,可能还需要添加一条拒绝理由的订单备注表的记录,以及状态变更日志表的记录。

此时,

订单对象是具体目标,更新主订单表中的状态是具体目标需要执行的动作,

订单备注表就是观察者1,它执行的动作是添加一条拒绝理由表记录

状态变更日志表也是观察者2,它执行的动作是添加状态变更日志表记录


但是,

观察者1和观察者2往往需要用到具体目标的订单编号和状态值,此时如何进行参数传递?

目前想到的方案:

  • 通过 $event_info 参数
  • 在抽象目标中执行notify的时候,可以传递一个update的参数,使其能在具体观察者中使用。

参考资料

转载于:https://www.cnblogs.com/zqunor/p/10836014.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值