php观察者模式
php观察者模式
1、php设计模式之观察者模式(Observer),当一个对象状态发生改变时,依赖它的对象全部收到通知,并自动更新。
2、场景:一个事件发生后,要执行一连串更新操作,传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新的逻辑增多之后,代码会变得
难以维护,这种方式是耦合的,侵入式的,增加新的逻辑需要修改事件主体的代码。
3、观察者模式实现了低耦合,非侵入式的通知与更新机制。
小示例:
公司发出一个通知,由各部门再通知本部门员工。
//被观察者:公司 class Company implements SplSubject{ protected $observers; public $content = '';//通知的内容 public $department = [];//需要通知的部门 public function __construct(){ $this->observers = new SplObjectStorage(); } //添加观察者 public function attach(SplObserver $observer){ //方法一:数组写法 // $this->observers[] = $observer; //方法二:使用SplObjectStorage()方法 $this->observers->attach($observer); } //删除观察者 public function detach(SplObserver $observer){ //方法一:数组写法 // $key = array_search($observer,$this->observers, true); // if($key){ // unset($this->observers[$key]); // } //方法二:使用SplObjectStorage()方法 $this->observers->detach($observer); } //通知观察者 public function notify() { foreach ($this->observers as $value) { if(!empty($this->department)){ if(!in_array(get_class($value),$this->department)){ continue; } } $value->update($this); } } //触发通知 public function contents($content = '',$department=[]) { $this->content = $content; $this->department = $department; $this->notify(); } } //定义观察者-生产部 class production implements SplObserver{ public function update(SplSubject $subject){ echo '生产部:'. $subject->content .'<br/>'; } } //定义观察者-销售部 class sales implements SplObserver{ public function update(SplSubject $subject){ echo '销售部:'. $subject->content .'<br/>'; } } //定义观察者-技术部 class technology implements SplObserver{ public function update(SplSubject $subject){ echo '技术部:'. $subject->content .'<br/>'; } } $companyCls = new Company(); $productionCls = new production(); $salesCls = new sales(); $technologyCls = new technology(); //添加三个观察者 $companyCls->attach($productionCls); $companyCls->attach($salesCls); $companyCls->attach($technologyCls); //触发通知 $companyCls->contents('过年放假七天'); //删除一个观察者 $companyCls->detach($salesCls); //注意:如果这里写new student()就不可以,那样要删除的对象和添加时的对象不是同一个 //触发通知 $companyCls->contents('中秋节快乐'); //添加一个新的观察者-财务部 class finance implements SplObserver{ public function update(SplSubject $subject){ echo '财务部:'. $subject->content .'<br/>'; } } $financeCls = new finance(); $companyCls->attach($financeCls); $companyCls->contents('会议室开会'); //触发通知个别部门加班 $companyCls->contents('本周末加班',['production','technology']);