PHP 程序设计之观察者模式的实现

  in   tech with  0  comment

什么是观察者模式?

一个对象通过添加一个方法(该方法允许另一个对象,即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些 观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。观察者模式是一种事件系统,意味着这一模式允许某个类观察另一 个类的状态,当被观察的类状态发生改变的时候,观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间紧密耦。

观察者模式有什么用?

上面的一段文字可能说的太过书面化,但是任何设计模式都是脱胎于实际的场景中,只要理解什么情况下需要用这种模式,基本就理解这种模式是干什么用的。比如用户登录这一行为,可能会产生积分赠送、登录日志写入、通知好友等等一系列操作。但是积分和日志以及通知模块通常是独立的。是否启用登录送积分,登录日志是否写入,通知哪些好友又是需要管理员可控的。并且要考虑后续程序功能模块的删改,所以按照正常类继承写法无疑对后续开发产生许多不可控的影响。于是,这时候就需要使用观察者模式。许多开源程序的插件机制,主题机制都是基于这种模式。

观察者模式要怎么实现?

既然是观察者模式,肯定有观察者和被观察者。首先我们把他们抽象出来。然后根据上面提出的问题,针对用户登录这一行为,实现观察者模式。

//抽象一个被观察者,并指定必要的抽象方法 abstract class observed{ //添加观察者,限制参数 abstract public function attach(observer $observer,$type); //删除观察者 abstract public function detach(observer $observer,$type); //通知 abstract public function notify($type); } //抽象一个观察者,并指定抽象方法 abstract class observer{ abstract public function update(observed $observed,$type); }

然后我们分别实例化一个被观察者和两个观察者,并实现其方法

//实例化一个被观察者对象,并实现抽象方法 class user extends observed{ CONST OBSERVER_TYPE_REGISTER = 1;//注册 CONST OBSERVER_TYPE_LOGIN = 2;//登录 //保存观察者 private $observers; public $name; //注意,实现抽象方法时可见性只能大于或者等于抽象方法 function attach(observer $observer,$type){ $this->observers[$type][] = $observer; } function detach(observer $observer,$type){ if($idx = array_search($observer, $this->observers[$type], true)){ unset($this->observers[$type][$idx]); } } //满足条件则通知观察者 function notify($type){ if(!empty($this->observers[$type])){ foreach($this->observers[$type] as $observer){ $observer->update($this,$type); } } } //模拟登录方法 function login($name){ $this->name=$name; //添加观察者[技巧:如果使用插件,则循环添加当前开启的插件即可] $point=new point(); $this->attach($point,self::OBSERVER_TYPE_REGISTER); $log=new log(); $this->attach($log,self::OBSERVER_TYPE_REGISTER); //通知观察者 $this->notify(self::OBSERVER_TYPE_REGISTER); } } //实例化观察者[积分] class point extends observer{ public function update(observed $observed,$type){ if($type==1){ //登录处理 echo 'login:add point '.$observed->name.'<br>'; } } } //实例化观察者[日志] class log extends observer{ public function update(observed $observed,$type){ if($type==1){ //登录处理 echo 'log:write log for '.$observed->name.'<br>'; } } } 在user中我们多增加了一个login方法来模拟登录这一行为。 //模拟登录 $user=new user(); $user->login('name');

执行之后我们会看到结果

login:add point name
log:write log for name

看到这里可能大家就明白了。观察者模式就是一个事件系统,一个对象去观察另一个对象的行为,并做出相应的处理。来避免各功能块之间的耦合,实现“低耦合”、“高聚合”这一概念

Responses