观察者模式代码实现

观察者模式是什么?

  观察者模式定义了一种一对多的依赖关系,让多个观察者对象监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有的观察者对象,使他们能够自动更新自己
应用场景
  当一个对象的改变需要同事改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
  观察者模式所作的工作其实就是在接触耦合。让耦合的双方都依赖于抽象类,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化
举个例子
  用户登录判断,记录用户是否非法登录次数过多;并根据登录的身份,显示不同的广告位。
       
 
    流程图如下:
      
          
上代码:
#观察者模式
## 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();

  

posted @ 2021-11-24 17:51  雷江生  阅读(128)  评论(0编辑  收藏  举报