PHP 设计模式 笔记与总结(11)观察者模式

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

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

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

【实例】

① 传统方式:

index.php

<?php

class Event{
    function trigger(){
        echo ‘Event happened<br />‘;
        
        //相关的更新操作,传统的方式是在事件代码之后,高耦合,侵入式
        echo ‘逻辑1更新操作<br />‘;
        echo ‘逻辑2更新操作<br />‘;
    }
}

$event = new Event();
$event->trigger();

 

② 观察者模式

\Common 下新建 EventGenerator.php

<?php
namespace Common;

//定义一个抽象类
abstract class EventGenerator{
    private $observer = array();
        function addObserver(Observer $observer){
            $this->observer[] = $observer;
        }
    //通知
    function notify(){
        foreach($this->observer as $observer){
            $observer->update();
        }
    }
}

 

\Common 下新建 Observer.php

<?php
namespace Common;

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

 

入口文件 index.php

<?php
define(‘BASEDIR‘,__DIR__); //定义根目录常量
include BASEDIR.‘/Common/Loader.php‘;
spl_autoload_register(‘\\Common\\Loader::autoload‘);
echo ‘<meta http-equiv="content-type" content="text/html;charset=utf8">‘;

class Event extends \Common\EventGenerator{
    function trigger(){
        echo ‘Event happened<br />‘;
        $this->notify();
    }
}

//编写观察者
//观察者1
class Observer1 implements Common\Observer{
    function update($server_info = null){
        echo "逻辑1更新操作<br />\n";
    }
}
//观察者2
class Observer2 implements Common\Observer{
    function update($server_info = null){
        echo "逻辑2更新操作<br />\n";
    }
}

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

输出:

Event happened
逻辑1更新操作
逻辑2更新操作

 

当事件发生之后,两个 Observer 的 update 会自动更新,都会被触发。

没有在事件主体中编写任何的耦合的逻辑1 或者 逻辑2。

而且可以动态的关闭某一观察者的逻辑(例如注释 $event->addObserver(new Observer1);)

 

【附】

echo "逻辑1更新操作<br />\n";

双引号时 \n 不会显示在输出结果中,页面换行通过<br />,查看源码换行通过 \n

如果换成单引号,则在页面中也会把 \ 和 n 显示出来,而且查看源码也不会换行。

所以要使用双引号把 \n 包起来。 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。