• PHP面向对象之观察者模式


        观察者模式按我的的理解,主要分为观察者类和被被观察者类二个部分。被观察者类会继承一个接口(如:Observable)实现对观察者的添加、删除和通知(即通知观察者发生了特定事件),它聚合了观察者类具体看原书类图。而观察者类继承一个接口(如:Observer)实现一个抽象方法update(),以下代码示例中此方法还将接收一个参数即被观察者,根据被观察者的状态来决定是否执行自身的业务逻辑。好了闲话不多说直接上代码。

    //被观察者类
    interface Observable {
        function attach(Observer $observer);    //添加观察者
        function detach(Observer $observer);    //删除观察者
        function notify();              //通知观察者
    }

    //一个处理登陆信息的类
    class Login implements Observable{
        const LOGIN_USER_UNKNOWN =1;
        const LOGIN_WRONG_PASS =2;
        const LOGIN_ACCESS =3;
        private $status = array();  //观察者的状态
        
        private $observers;  //保存观察者对象
        
        function __construct (){
            $this->observers = array();
        }
        
        function attach(Observer $observer){
            $this->observers[] = $observer;
        }
        
        function detach(Observer $observer){
            $newobservers = array();
            foreach(|$this->observers as $obs){
                if($obs !== $observer){
                    $newobservers[]=$obs;
                }
            }
            $this->observers = $newobservers;
        }
        
        function notify(){
            foreach($this->observers as $obs){
                $obs->update($this);
            }
        }
        
        function handleLogin($user,$pass,$ip){
            switch(rand(1,3)){                  //这里模拟了3种登陆状态
                case 1:
                    $this->setStatus(self::LOGIN_ACCESS,$user,$ip);  //设置被观察者的状态,通知观察者后,观察者将跟据状态来执行相应的业务逻辑
                    $ret =true;
                    break;
                case 2:
                    $this->setStatus(self::LOGIN_WRONG_PASS,$user,$ip);
                    $ret =false;
                    break;
                case 3:
                    $this->setStatus(self::LOGIN_USER_UNKNOWN,$user,$ip);
                    $ret =false;
                    break;
            }        
            $this->notify():
            return $ret;
            //...............
        }
        
        private function setStatus($status,$user,$ip){
            $this->status = array($status,$user,$ip)
        }
    }

    //观察者类
    interface Observer{
        function update(Observable $observable);
    }


    //这个类主要是为了确保传递过来的被观察者对象是login类,因为只有login才有setStatus方法,上面的Observer为了保证它的通用性所以没有加入抽象方法setStatus
    abstract class LoginObserver implements Observer{  
        private $login;
        function __construct (Login $login){
            $this->login=$login;
            $login->attach($this);
        }
        function update(Observable $observable){
            if($observable === $this->login){
                $this->doUpdate($observable);
            }
        }
        
        abstract function doUpdate(Login $login);
    }


    class SecurityMonitor extends LoginObserver{  //登陆时密码错误的话就发邮件给管理者
        function doUpdate(Login $login){
            $status = $login->getStatus();
            if($status[0] == Login::LOGIN_WRONG_PASS){
                //发送邮件
            }
        }
    }

    class GeneralLogger extends LoginObserver{    //..........
        function doUpdate(Login $login){
            $status = $login->getStatus();    
            //记录登陆数据
        }
    }

    class partnershipTool extends LoginObserver{      //.........
        function doUpdate(Login $login){
            $status = $login->getStatus();    
            //检查iP,设置Cookie    
        }
    }

     //客户端代码
    $login = new Login();
    new SecurityMonitor($login);
    new GeneralLogger($login);
    new PartnershipTool($login);

    $login->handleLogin('test','test','test');

    最后: 路漫漫其修远兮,吾将上下而求索!

  • 相关阅读:
    Ubuntu 12.10 安装破解sublimetext 2
    封装一个类型转换的方法
    【转】CultureInfo中重要的InvariantCulture
    C# 36进制转10进制
    用泛型的IEqualityComparer<T>接口去重复项
    关于wamp启动是80端口被占用的问题详解(win7系统下WAMP 80端口被MicrosoftHTTPAPI/2.0占用的解决办法)
    Ubuntu 更改鼠标滚轮速度
    edge ctrl+c 复制不起作用
    centos 7 mysql8 安装和卸载
    Windows Terminal 终端 SSH连接centos7 linux
  • 原文地址:https://www.cnblogs.com/kerryw/p/6876130.html
Copyright © 2020-2023  润新知