观察者模式

## 定义

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会受到通知并自动更新。

 

## 设计原则

1. 为了交互对象之间的松耦合设计。

2. 观察者模式中,会改变的是主题的状态,以及观察者的数目的类型,利用这个模式,可以改变依赖于主题状态的对象,却不必改变主题。(<font color='red'>找出程序中会变化的方面,然后将其和固定不变的方面相分离</font>)

3. 主题与观察者都使用接口,观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者,这样可以让两者之间运作正常,又同时具备松耦合的优点。(<font color='red'>针对接口编程,不针对实现编程</font>)

## 使用场景

一个主题改变后需要通知不同类型的实体进行改变的场景。

## 实现要点

 

1. 定义观察者集合,并定义针对集合的添加、删除操作,用于增加、删除订阅者(观察者)

2. 定义通知方法,用于将新情况通知给观察者用户(订阅者用户)

## 补充

 可以增加一个change状态来标识是否需要作出通知。

setChange();    // 设置为可通知

clearChange();    // 设置为不可通知

hasChange();    // 获取现在的标志位状态

## 代码示例

 

``` php

<?php

 

/**

* 被观察者接口

*/

interface Observable {

    /**

    * 添加/注册观察者

    * @param  Observer $observer 观察者对象

    */

    public function attach(Observer $observer);

 

    /**

    * 删除观察者

    * @param  Observer $observer 观察者对象

    */

    public function detach(Observer $observer);

 

    /**

    * 触发通知

    */

    public function notify();

}

 

 

/**

* 观察者接口

*/

interface Observer {

    // 接收到通知的处理方法

    public function update(Observable $observable);

}

 

 

 

/**

* 被观察者实体

*/

class Video implements Observable {

 

    // 订阅者

    public $observers = [];

 

    // 唱片名称

    private $recordName;

    // 唱片价格

    private $recordPrice;

 

 

    /**

    * 构造方法

    */

    public function __construct($recordName, $recordPrice)

    {

        $this->recordName  = $recordName;

        $this->recordPrice = $recordPrice;

    }

 

    /**

    * 魔术方法 set

    */

    public function __set($key, $value)

    {

        $this->$key = $value;

    }

 

    /**

    * 魔术方法 get

    */

    public function __get($key)

    {

        return $this->$key;

    }

 

    // 添加/注册观察者

    public function attach(Observer $observer)

    {

        if(!in_array($observer, $this->observers)) {

            $this->observers[] = $observer;

        }

    }

 

    // 删除观察者

    public function detach(Observer $observer)

    {

        $key = array_search($observer, $this->observers);

        if($key === false) {

            unset($this->observers[$key]);

        }

    }

 

    // 触发通知

    public function notify()

    {

        foreach ($this->observers as $observer) {

            // 把本类对象传给观察者

            $observer->update($this);

        }

    }

 

    /**

    * 发布

    */

    public function publish()

    {

        $this->notify();

    }

 

}

 

 

/**

* 观察者实体

*/

class LaoWang implements Observer {

    public function update(Observable $observable){

        echo '唱片名称:' . $observable->recordName . "<br/>" . '价格:' . $observable->recordPrice;

    }

}

 

// 黑豹音乐唱片

$blackPanther = new Video('have no place', 18);

$laoWang = new LaoWang();

 

$blackPanther->attach($laoWang);

// 发布

$blackPanther->publish();

 

 

?>

```

本文章为读《HEAD FIRST 设计模式》笔记记录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值