什么是观察者模式?
观察者设计模式能够更便利地创建查看目标对象状态的对象,并且提供与核心对象非耦合的指定功能性。
该模式非常简单:一个对象通过添加一个方法(该方法允许另一个对象,即观察者 注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者使用该信息执行的操作与可观察的对象无关。结果是对象可以相互对话,而不必了解原因。
uml
该图详细说明了一个使用观察者设计模式的类设计:
下面是对上图的说明:
1.myobject是可观察对象,它包含一个名为observers的观察者保护数组。公共方法addobserver()接受一个观察者的实例并将其存储在观察者数组内。
2.dosomething()公共方法会被调用,这个方法对myobject应用状态变化。随后,notify()公共方法会被调用,这个方法可遍历循环观察者数组。
3.myobjectobserver具有一个名为change()的公共方法,该方法接受myobject的一个实例。这个特定的观察者接下来会对myobject的内容执行某些操作。当在观察者数组中找到特定的观察者时,myobject的notify()方法会直接调用change()方法。
使用实例:
<?php  
interface observable{  
    function attach( observer $observer );  
    function detach( observer $observer );  
    function notify();  
}  
  
  
class login implements observable{  
    const login_user_unknow = 1;  
    const login_wrong_pass = 2;  
    const login_access = 3;  
    private $status = array();  
    private $observers = array();  
  
    public function setstatus( $status, $user, $ip ) {  
        $this->status = array( $status, $user, $ip );  
    }  
    public function getstatus() {  
        return $this->status;  
    }  
    public function handlelogin( $user, $pass, $ip ) {  
        switch ( mt_rand( 1, 3 ) ) {  
        case 1:  
            $this->setstatus( self::login_user_unknow, $user, $ip );  
            $ret = false;  
            break;  
        case 2:  
            $this->setstatus( self::login_wrong_pass, $user, $ip );  
            $ret = false;  
            break;  
        case 3:  
            $this->setstatus( self::login_access, $user, $ip );  
            $ret = true;  
            break;  
        }  
        $this->notify();  
        return $ret;  
    }  
  
  
    public function attach( observer $observer ) {  
        $this->observers[] = $observer;  
    }  
  
    public function detach( observer $observer ) {  
        $newobservers = array();  
        foreach ( $this->observers as $obs ) {  
            if ( $obs !== $observer )  
                $newobservers[] = $obs;  
        }  
        $this->observers = $newobservers;  
    }  
  
    public function notify() {  
        foreach ( $this->observers as $obs ) {  
            $obs->update( $this );  
        }  
    }  
}  
  
interface observer{  
    function update( observable $observable );  
}  
  
class securitymonitor implements observer{  
    function update( observable $observable ) {  
        $status = $observable->getstatus();  
        if($status[0] == login::login_wrong_pass){  
            echo __class__.":".$status[1]."于".$status[2]."登录失败";  
        }  
    }  
}  
  
$login = new login();  
$login->attach(new securitymonitor());  
$login->handlelogin('xxx','xxx','127.0.0.1');  
?>  
出错时的运行结果:  
securitymonitor:xxx于127.0.0.1登录失败[finished in 0.1s]
代码中可以看到login对象主动添加securitymonitor对象观察。这样要调用login::getstatus(),securitymonitor类就必须了解更多信息。虽然调用发生于一个observable对象上,但无法保证对象也是一个login对象。为解决这个问题,有一个办法:断续保持observable接口的通用性,由observer类负责保证它们的主体是正确的类型。它们甚至能将自己添加到主体上。
以上就是php面向对象进阶设计模式:观察者模式使用实例的详细内容。
   
 
   