观察者模式实践应用php,PHP 观察者模式 的真正实现

1.不是示例代码,而是实际应用代码. 2.多个观察者,多个被观察者 3.根据业务情况,观察者与被观察者都是单例的. 统称为 业务逻辑处理单元(Unit) 1.先实现 处理单元的基类 ,主要实现单例 <?php /**  * 所有业务逻辑处理单元的基类,实现了单例化  * @author bluehire  *  */ class SUnit {          /**      * 禁止实例化      */     protected function __construct(){     }          /**      * 获取本类单例的方法,公开      *      * @return SUnit      */     public static function instance() {         //延迟绑定的句柄,子类单例,而不是基类         if(static::$handle){             return static::$handle;         }                  //这个是延迟绑定的,运行时的子类的类名         $class = get_called_class();         static::$handle = new $class();         return static::$handle;     } } 2.现具体实现一个 观察者(以日志为例,这个是最常用的,而且足够简单)   这里对普通观察者进行了一次扩展,允许带一个参数   原因解释一下:  同一个被观察者可能在业务的不同阶段通知同一个观察者,  我想明确告知 观察者 当前阶段之类的信息,    本来可以用被观察者对象的属性来实现,但感觉太绕了,不明确. <?php /**  * 文本日志处理单元,观察者模式  * @author bluehire  *  */ class ULog extends SUnit implements SplObserver {     protected static $handle; //单例句柄          /**      * 得到了被观察者的一个通知      * @see SplObserver::update()      */     public function update(SplSubject $object,$params=null){         //需要被观察者提供一个日志文件名         $file=$object->getLogFile($params);                  //需要被观察者提供一个日志内容         $msg=$object->getLogMsg($params);                  //具体干活         writeLog($file, $msg);         } } 3.根据以上,如果一个被观察者 要想 被  日志观察者 观察(这话可真费劲), 就要实现两个方法,  所以,这就导致了一个接口 <?php /**  * 所有需要日志观察者的被观察者要实现的接口  * @author bluehire  *  */ interface ILogSubject extends SplSubject{     /**      * 要提供日志文件名      */     public function getLogFile($params=null);          /**      * 要提供日志内容      */     public function getLogMsg($params=null); } 4.现在终于轮到 被观察者了, 所有被观察者都有三个 固定方法,我实现到基类中 <?php /**  * 被观察者(观察者设计模式)的基类,父类为业务逻辑处理单元(实现了单例化)  * @author bluehire  *  */ class SSubject extends SUnit{     //当前被观察者的所有观察者     private $observers=array();          /**      * 增加一个观察者      * @param SplObserver $observer      * @return SSubject      */     public function attach(SplObserver $observer){         $this->observers[]=$observer;         return $this;     }          /**      * 取消一个观察者,这个不常用      * @param SplObserver $observer      * @return SSubject      */     public function detach(SplObserver $observer){         $idx = array_search ( $observer, $this->observers, true );         if ($idx) {             unset ( $this->observers [$idx] );         }         return $this;     }          /**      * 通知所有观察者      * @param 可以带一个参数,发送给所有观察者,观察者会将此参数用于回调被观察者的方法      * @return SSubject      */     public function notify($params=null){         foreach ( $this->observers as $observer ) {             $observer->update ( $this,$params );         }         return $this;     } } 5.开始具体的被观察者,以订单为例 <?php /**  * 订单处理单元,作为 被观察者  * @author bluehire  *  */ class UOrder extends SSubject implements ILogSubject{     protected static $handle; //单例句柄          /**      * 单例,      * @see SUnit::instance()      * @return UOrder      */     public static function instance(){         //附加文本日志观察者         parent::instance()->attach(ULog::instance());         return self::$handle;     }          //所有观察者     private $observers=array();          /**      * 为日志观察者提供日志文件名      * @see ILogSubject::getLogFile()      */     public function getLogFile($params=null){         return 'order';     }          /**      * 为日志观察者提供日志内容      * @see ILogSubject::getLogMsg()      */     public function getLogMsg($params=null){         return $params;     }                    public function something(){         //......         $this->notify(array('a'=>1));     } } 以上程序实测通过,部分代码请自行修改(如dump,writeLog), 现在说适用范围: 设计 模式这东西,绝对不是随便就可以用的, 简单业务逻辑使用这东西就是个找死.我这里也是因为业务复杂到应该使用一部分设计模式 多个观察者,多个被观察者 才需要使用这个模式 , 未完事项: 我仍在纠结,要不要使用观察者模式, 相比 过程化的消息通知机制(  被观察者 逐个 通知 观察者,使用 设计 好的 接口), 体会不到好处. 欢迎讨论 Q:31008088

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值