设计模式之观察者模式PHP实现

1、观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且有所作为。即出版者+订阅者=观察者模式。

2、例子类图概览:

 

3、假设我们需要实现一个气象台,当气象信息更新时候,通知到每一个布告板上。

(1)我们根据上图将所需接口列出如下:

<?php

/**
 * 主题接口
 * Interface Subject
 */


interface Subject{
    public function registerObserver(Observer $O);
    public function removeObserver(Observer $O);
    public function notifyObservers();
}
<?php

/**
 * 观察者接口
 * Interface Observer
 */
interface Observer{
    public function update($fltTemperature, $fltHumidity, $fltPressure);
}
<?php

/**
 * 展示接口
 * Interface DisplayElement
 */

interface DisplayElement{
    public function display();
}

(2)然后我们实现主题接口如下:

<?php

class WeatherData implements Subject{

    public $arrObserver = array();
    public $fltTemperature;
    public $fltHumidity;
    public $fltPressure;

    /**
     * 添加观察对象
     * @param Observer $O
     */
    public function registerObserver(Observer $O)
    {
        $this->arrObserver[] = $O;
    }

    /**
     * 移除观察对象
     * @param Observer $O
     */
    public function removeObserver(Observer $O)
    {
        foreach ($this->arrObserver as $key => $o){
            if($o == $O){
                unset($this->arrObserver[$key]);
            }
        }
    }

    /**
     * 通知观察对象更新数据
     */
    public function notifyObservers()
    {
        foreach ($this->arrObserver as $key => $o){
            $o->update($this->fltTemperature, $this->fltHumidity, $this->fltPressure);
        }
    }

    /**
     * 当信息更新时候调用通知接口
     */
    public function measurementsChange(){
        $this->notifyObservers();
    }

    /**
     * 更新信息
     * @param $fltTemperature
     * @param $fltHumidity
     * @param $fltPressure
     */
    public function setMeasurements($fltTemperature, $fltHumidity, $fltPressure){
        $this->fltTemperature = $fltTemperature;
        $this->fltHumidity = $fltHumidity;
        $this->fltPressure = $fltPressure;
        $this->measurementsChange();
    }
}

(3)我们再实现观察者接口如下:

<?php

/**
 * 当前天气情况布告板
 * Class CurrentCondition
 */
class CurrentCondition implements Observer, DisplayElement{
    public $fltTemperature;
    public $fltHumidity;
    public $fltPressure;

    public function update($fltTemperature, $fltHumidity, $fltPressure)
    {
        $this->fltTemperature = $fltTemperature;
        $this->fltHumidity = $fltHumidity;
        $this->fltPressure = $fltPressure;
        $this->display();
    }

    public function display()
    {
        echo "now condition is: temperatur={$this->fltTemperature}, humidity={$this->fltHumidity}, pressure={$this->fltPressure}";
    }
}
<?php

/**
 * 天气预报接口
 * Class Forcast
 */
class Forcast implements Observer, DisplayElement{
    public $fltTemperature;
    public $fltHumidity;
    public $fltPressure;

    public function update($fltTemperature, $fltHumidity, $fltPressure)
    {
        $this->fltTemperature = $fltTemperature;
        $this->fltHumidity = $fltHumidity;
        $this->fltPressure = $fltPressure;
        $this->display();
    }

    public function display()
    {
        if($this->fltTemperature > 30 && $this->fltHumidity > 70 && $this->fltPressure > 80){
            echo 'it will be hot';
        }else{
            echo 'it will be cool';
        }
    }
}

(4)最后我们对相关接口进行调用输出:

<?php

$objWeather = new WeatherData();
$objWeather->setMeasurements(40,20,50.9);
$objWeather->setMeasurements(20,40,30.7);
$objWeather->setMeasurements(10,50,60.2);

 

posted @ 2019-05-28 23:20  cfYu  阅读(434)  评论(0编辑  收藏  举报