zoukankan      html  css  js  c++  java
  • 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']);

      

  • 相关阅读:
    [BZOJ3884] 上帝与集合的正确用法
    [BZOJ3518] 点组计数
    [BZOJ3601] 一个人的数论
    [BZOJ3529] [Sdoi2014]数表
    原生js实现无缝滚动轮播图-点击页码即刻显示该页码的内容
    原生js实现无缝滚动轮播图
    vue封装tinymce富文本组件,图片上传回调方法
    vue-cli项目结合Element-ui基于cropper.js封装vue图片裁剪组件
    js实现多文件上传(二)-- 拖拽上传
    js实现多文件上传(一)-- 图片转base64回显
  • 原文地址:https://www.cnblogs.com/gyfluck/p/9679757.html
Copyright © 2011-2022 走看看