PHP深入观察者模式

北城余情 提交于 2020-03-01 06:12:29

####观察者模式

  • 设计观察者是为了让一个对象跟踪某个状态,知道状态如何改变,一旦状态改变,所有订阅的对象都能得到通知

#####使用SPL实现观察者模式

  • Splsubject 接口有三个抽象方法 attach(),detach(),notify()这些方法不返回任何结果
  • SplObserver 接口有一个方法update()它会得到subject状态的最新状态并交给观察者实例
  • SplObjectStorage 类描述为从对象到数据或对象集的一个映射
<?php
/**
 * Created by PhpStorm.
 * User: gewenrui
 * Date: 16/3/14
 * Time: 下午7:46
 */
//继承Splsubject接口
class ConcreteSubject implements SplSubject{
    private $observers;
    private $data;
    //实例化仓库
    public function setObservers(){
        $this->observers = new SplObjectStorage();
    }
    //添加观察者
    public function attach(\SplObserver $observer){
        $this->observers->attach($observer);
    }
	//删除观察者
    public function detach(\SplObserver $observer){
        $this->observers->detach($observer);
    }
    //通知转发
    public function notify(){
        foreach($this->observers as $observer){
            $observer->update($this);
        }
    }
    //设置数据
    public function setData($dataNow){
        $this->data = $dataNow;
    }
    public function getData(){
        return $this->data;
    }
}
//SPL具体观察者
class ConcreteObserver implements SplObserver{
    public function update(SplSubject $subject)
    {
      echo $subject->getData();
    }
}
class Client{
    public function __construct()
    {
        echo "

 create three new concrete observers ";
        //创建观察者
        $ob1 = new ConcreteObserver();
        $ob2 = new ConcreteObserver();
        $ob3 = new ConcreteObserver();

        $subject = new ConcreteSubject();
        $subject->setObservers();
        $subject->setData("here is u data"."</br>");
        $subject->attach($ob1);
        $subject->attach($ob2);
        $subject->attach($ob3);
        $subject->notify();
        echo "<p> Reset data and reattach ob3
";
        $subject->setData("more data that only"."</br>");
        $subject->attach($ob3);
        $subject->attach($ob2);
        $subject->notify();
    }
}
$data = new Client();

#####自由的PHP和观察者模式

<?php
/**
 * Created by PhpStorm.
 * User: gewenrui
 * Date: 16/3/14
 * Time: 下午8:24
 */
namespace abbbbb;
//一个接口,一个抽象类,一个继承抽象类的具体类
//观察者实体实现借口类
interface Observer{
    function update(Subject $subject);
}
abstract  class Subject{
    protected $stateNow;
    protected $observers = array();
    public function attachObser(Observer $obser){
        //array_push() 函数向第一个参数的数组尾部添加一个或多个元素(入栈),然后返回新数组的长度。
        array_push($this->observers,$obser);
    }
    public function detachObser(Observer $obser){
        //从数组中移除 数据
        $position = 0;
        foreach($this->observers as $viwer){
            ++$position;
            if($viwer == $obser){
                array_splice($this->observers,($position),1);
            }
        }
    }
    public function notify(){
        foreach($this->observers as $viewer){
            //调用update方法
            $viewer->update($this);
        }
    }
}
class ConcreteSubject extends Subject{
    public function setState($stateSet){
        $this->stateNow = $stateSet;
    }
    public function getState(){
        return $this->stateNow;
    }
}
class ConcreteObserverDT implements Observer{
    private $currentState;
    public function update(Subject $subject)
    {
       $this->currentState = $subject->getState();
        echo "DT";
    }
}
class ConcreObserverTablet implements Observer{
    private $currentState;
    public function update(Subject $subject)
    {
        $this->currentState = $subject->getState();
        echo "tablet";
    }
}
class ConcreObserverPhone implements Observer{
    private $currentState;
    public function update(Subject $subject)
    {
        $this->currentState = $subject->getState();
        echo "phone";
    }
}

class Client{
    public function __construct()
    {
        $sub = new ConcreteSubject();

        $ob1 = new ConcreObserverPhone();
        $ob2 = new ConcreObserverTablet();
        $ob3 = new ConcreteObserverDT();

        $sub->attachObser($ob1);
        $sub->attachObser($ob2);
        $sub->attachObser($ob3);
        $sub->setState("fuck");
        $sub->detachObser($ob1);
        $sub->notify();

    }
}
$data = new Client();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!