php 观察者模式

/*
观察者模式:观察者模式属于行为模式,是定义对象间的一种一对多的依赖关系,
以便当一个对象(主体)的状态发生改变时,所有依赖于它的对象(观察者)都得到通知并自动更新。
它完美的将观察者对象和被观察者对象分离。可以在独立的对象(主体)中维护一个
对主体感兴趣的依赖项(观察者)列表。让所有观察者各自实现公共的Observer接口,
以取消主体和依赖项之间的直接依赖关系。
 */

/**
 *接口:主体功能
 *@author li.yonghuan
 *@version 2014.01.18
 */
interface Observable{
    /**
     *添加观察者
     */
    function attach( Observer $observer );

    /**
     *删除观察者
     *
     */
    function detach( Observer $observer );

    /**
     *通知观察者
     *
     */
   function notify();
}

/**
 *主体类
 *被观察者
 *@author li.yonghuan
 *@version 2014.01.18
 */
class Login implements Observable{
    /**
     *密码错误状态
     *
     */
    const LOGIN_ACCESS = 1;
    const LOGIN_WRONG_PASS = 2;
    const LOGIN_USER_UNKNOWN = 3;

    /**
     *登录时的状态
     *
     */
    private $loginstatus;

    /**
     *观察者列表
     *@var array
     */    
    private $observers;

    /**
     *构造方法
     *
     */
    public function __construct(){
        $this->observers = array();
    }

    /**
     *添加观察者
     *@param $observer Observer object
     */
    public function attach( Observer $observer ){
       $this->observers[] = $observer; 
    }

    /**
     *删除观察者
     *@param $observer Observer object
     */
    public function detach( Observer $observer ){
        $newobservers = array();
        foreach( $this->observers as $obs ){
            if( $obs != $observer ){
                $newobservers[] = $observer;
            }
        } 
        $this->observers = $newobservers;
    }

    /**
     *通知观察者
     *
     */
    public function notify(){
        foreach( $this->observers as $obs ){
            $obs->update( $this );
        }
    }

    /**
     *处理登录
     *@param $user string 用户名
     *@param $pass string 密码
     *@param $ip string IP地址
     */
    public function handleLogin( $user='li.yonghuan', $pass='123456', $ip='127.0.0.1' ) {
        switch( rand(1,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;
    }

    /**
     *设置状态值
     *@param $status string 状态值
     *@param $user string 用户名
     *@param $ip string IP地址
     */
    public function setStatus( $status, $user, $ip ) {
       $this->loginstatus = array( $status, $user, $ip ); 
    }


    /**
     *获取状态
     *登录时产生的各种状态
     */
    public function getStatus() {
        
        return $this->loginstatus;
    }
}

/**
 *接口:观察者
 *@author li.yonghuan
 *@version 2014.01.18
 *
 */
interface Observer {
    /**
     *更新
     */
    function update( Observable $observable );
}

/**
 *抽象类,登录观察者
 *@author li.yonghuan
 *@version 2014.01.18
 *
 */
abstract class LoginObserver implements Observer {
    /**
     *Login 对象
     *@var Login object
     */
    private $login;

    /**
     *构造方法
     *@param $login Login object
     */
    public function __construct( Login $login ) {
       $this->login = $login; 
       $login->attach( $this );
    }

    /**
     *更新操作
     *@param $observer Observer
     */
    public function update( Observable $observable ) {
        if( $observable === $this->login ) {
            $this->doUpdate( $observable );
        } 
    }

    /**
     *执行更新
     *@param login Login
     */
    abstract function doUpdate( Login $login );

}

/**
 *安全监控登录,负责登录安全的观察者
 *@author li.yonghuan
 *@version 2014.01.18
 */
class SecurityMonitor extends LoginObserver {
    /**
     *执行更新
     *@param $login Login
     */
    public function doUpdate( Login $login ) {
       $status = $login->getStatus(); 
       if( $status[0] == Login::LOGIN_WRONG_PASS ) {
           //发送邮件给系统管理员
           print __CLASS__.":\tsending mail to sysadmin"; 
       }
    }
}

/**
 *正确登录,观察者
 *@author li.yonghuan
 *@version 2014.01.18
 */
class GeneralLogger extends LoginObserver {
   /**
    *观察者更新
    *
    */ 
    public function doUpdate( Login $login ) {
        $status = $login->getStatus(); 
       if( $status[0] == Login::LOGIN_ACCESS ) {
           //记录登录数据到日志
           print __CLASS__.":\tadd login data to log"; 
       }       
    }
}

/**
 *用户名错误,观察者
 *@author li.yonghuan
 *@version 2014.01.18
 */
class UserMonitor extends LoginObserver {
   /**
    *观察者更新
    *
    */ 
    public function doUpdate( Login $login ) {
        $status = $login->getStatus(); 
       if( $status[0] == Login::LOGIN_USER_UNKNOWN ) {
           //用户名错误
           print __CLASS__.":\tusername is uncorrect"; 
       }       
    }
}

//测试
$login = new Login();
//添加安全观察者
new SecurityMonitor( $login );
//添加正确登录观察者
new GeneralLogger( $login );
//添加用户名观察者
new UserMonitor( $login );

//开始登录
$login->handleLogin();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
观察者模式是一种设计模式,它允许对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在 PHP 中,可以使用 SplSubject 和 SplObserver 接口来实现观察者模式。具体实现方式可以参考以下代码: <?php // 定义主题接口 interface Subject { public function attach(Observer $observer); public function detach(Observer $observer); public function notify(); } // 定义观察者接口 interface Observer { public function update(Subject $subject); } // 实现主题类 class ConcreteSubject implements Subject { private $observers = array(); private $state; public function attach(Observer $observer) { $this->observers[] = $observer; } public function detach(Observer $observer) { $key = array_search($observer, $this->observers, true); if ($key !== false) { unset($this->observers[$key]); } } public function notify() { foreach ($this->observers as $observer) { $observer->update($this); } } public function setState($state) { $this->state = $state; $this->notify(); } public function getState() { return $this->state; } } // 实现观察者类 class ConcreteObserver implements Observer { private $name; public function __construct($name) { $this->name = $name; } public function update(Subject $subject) { echo "Observer {$this->name} has been notified with state {$subject->getState()}\n"; } } // 使用示例 $subject = new ConcreteSubject(); $observer1 = new ConcreteObserver('Observer 1'); $observer2 = new ConcreteObserver('Observer 2'); $observer3 = new ConcreteObserver('Observer 3'); $subject->attach($observer1); $subject->attach($observer2); $subject->attach($observer3); $subject->setState('state 1'); $subject->setState('state 2'); $subject->detach($observer2); $subject->setState('state 3'); ?> 以上代码实现了一个简单的观察者模式,主题类 ConcreteSubject 维护了一个观察者列表,当主题状态发生改变时,会通知所有观察者进行更新。观察者类 ConcreteObserver 实现了更新方法,当被通知时,会输出当前主题状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值