观测者模式

PHP5.1以上自带了观察者、被观察者模式的接口:SplSubject

<?php

class user implements SplSubject {  // 注意:这里必须继承SplSubject

  public $lognum;

   public $hobby;

  //存储对象

  protected $observers = null;

 

  public function __construct($hobby) {

    $this->lognum = rand(1,10);

    $this->hobby = $hobby;

    //PHP自带的用来存储观察者对象用的类

    $this->observers = new SplObjectStorage();

  }

  public function login() {

          $this-> notify();

  }

  //加入观察范围中

  public function attach( SPLObserver $observer) {

    $this->observers-> attach($observer);

  }

  //踢出观察范围中

  public function detach( SPLObserver $observer) {

    $this->observers-> detach($observer);

  }

  //通知观察的对象,循环添加

  public function notify() {

    $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 == 'sport' ) {

         echo '台球比赛门票预订';

    } else {

         echo '好好学习天天向上';

    }

  }

}

//实施观察

$user = new user('sports');

$user->attach(new secrity());

$user->attach(new ad());

$user->login();//通知观察者改变的内容



下面是不用PHP自带的函数实现观察者模式:

<?php

class Paper{ /* 主题    */
     private $_observers = array ();
 
     public function register( $sub ){ /*  注册观察者 相当于attach*/
         $this ->_observers[] = $sub ;
     }
 
     
     public function trigger(){  /*  外部统一访问    相当于notify*/
         if (! empty ( $this ->_observers)){
             foreach ( $this ->_observers as $observer ){
                 $observer ->update();
             }
         }
     }
}
 
/**
  * 观察者要实现的接口
  */
interface Observerable{
     public function update();
}
 
class Subscriber implements Observerable{
     public function update(){
         echo "Callback\n" ;
     }
}

 

下面是测试代码

/*  测试    */
$paper = new Paper();
$paper ->register( new Subscriber());
//$paper->register(new Subscriber1());
//$paper->register(new Subscriber2());
$paper ->trigger();

 

总结
       
 当新对象要填入的时候,只需要在主题(又叫可观察者)中进行注册(注册方式很多,你也可以在构造的时候,或者框架访问的接口中进行注册),然后实现代码直接在新对象的接口中进行。这降低了主题对象和观察者对象的耦合度。
 
好的设计模式不会直接进入你的代码中,而是进入你的大脑中。


你可能感兴趣的:(观测者模式)