zoukankan      html  css  js  c++  java
  • 观察者模式代码实现

    观察者模式是什么?

      观察者模式定义了一种一对多的依赖关系,让多个观察者对象监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使他们能够自动更新自己
    应用场景
      当一个对象的改变需要同事改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
      观察者模式所作的工作其实就是在接触耦合。让耦合的双方都依赖于抽象类,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化
    举个例子
      用户登录判断,记录用户是否非法登录次数过多;并根据登录的身份,显示不同的广告位。
           
     
        流程图如下:
          
              
    上代码:
    #观察者模式
    ## PHP5 提供观察者 observer 与 被观察者 subject 的接口
    class User implements SplSubject {
        public $lognum;//登录次数
        public $hobby; // 爱好
        protected $observers = null; // 存储对象
    
        /**
         * 登录初始化赋值
         * user constructor.
         * @param $hobby
         */
        public function __construct($hobby)
        {
            $this->lognum = rand(1,10);
            $this->hobby = $hobby;
            $this->observers = new SplObjectStorage();//储存对象的类
        }
    
        /**
         * 观察登录次数,触发 广告 和 商务 类,处理相关逻辑
         */
        public function login(){
            // 操作session
            // 登录就触发通知观察者
            $this->notify();
        }
        /**
         * 添加被观察者类
         * @param SPLObserver $observer
         */
        public function attach(SPLObserver $observer){
            $this->observers->attach($observer);
        }
    
        /**
         * 删除被观察者
         * @param SplObserver $observer
         */
        public function detach(SplObserver $observer){
            $this->observers->detach($observer);
        }
    
        /**
         *  通知被观察者
         */
        public function notify()
        {
            // TODO: Implement notify() method.
            $this->observers->rewind();
            while($this->observers->valid()){
                $observer = $this->observers->current();
                $observer->update($this);// 通知自己
                $this->observers->next();
            }
        }
    }
    
    #观察者类 安全
    class Secrity implements SPLObserver {
        public function update(SplSubject $subject){
            if( $subject->lognum < 3 ){
                echo '这是第'. $subject->lognum.'次安全登录';
            }else{
                echo '这是第'. $subject->lognum.'次登录,异常';
            }
        }
    }
    #观察者类 广告
    class Ad implements SplObserver {
        public function update(SplSubject $subject){
            if( $subject->hobby == 'sports' ) {
                echo '台球英锦赛门票预订';
            }else{
                echo '好好学习,天天向上';
            }
        }
    }
    
    // 实现观察
    $user = new User('sports');
    $user->attach(new Secrity());
    $user->attach(new Ad());
    $user->login();
    

      

    分享技术,方便你我他。
  • 相关阅读:
    HDU 3511 圆的扫描线
    POJ 2540 半平面交
    POJ 2451 半平面交nlogn
    POJ 3525 半平面交
    HDU 3629 极角排序
    POJ 1274 半平面交
    POJ 1696 凸包变形
    POJ 3384 半平面交
    Flex SDK代码规范之命名
    Flash & Flex组件优化的杀手锏callLater
  • 原文地址:https://www.cnblogs.com/leijiangsheng/p/15599272.html
Copyright © 2011-2022 走看看