一个菜鸟驿站!

浅谈设计模式-观察者模式

PHP 2018-07-26 浏览(1511) 评论(0)
- N +

文章目录 [+]

什么是观察者模式

timg.jpeg

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

场景

当一个事件发生后,要执行一连串更新操作,传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新逻辑增多之后,代码变得难以维护,这种方式是耦合式的,侵入式的,增加新的逻辑需要改变事件主题的代码。

观察者模式实现了低耦合,非侵入式的通知与更新。


观察者模式主要角色

  1. 抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有多个观察者。抽象主题提供了增加和删除观察者对象的接口。

  2. 抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己。

  3. 具体主题(ConcreteSubject)角色:存储相关状态到具体观察者对象,当具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个具体子类实现。

  4. 具体观察者(ConcretedObserver)角色:存储一个具体主题对象,存储相关状态,实现抽象观察者角色所要求的更新接口,以使得其自身状态和主题的状态保持一致。

330a2cf304a1b0717fd5ddf1.jpeg


观察者模式的优点和确定

观察者模式的优点:

  1. 观察者和主题之间的耦合度较小;

  2. 支持广播通信。

观察者模式的缺点:

  1. 由于观察者并不知道其他观察者的存在,它可能对改变目标的最终代价一无所知。这可能会引起意外的更新。

简单代码实例

<?php
/**
 * Created by PhpStorm.
 * User: 猫巷
 * Email:catlane@foxmail.com
 * Date: 18-7-26
 * Time: 上午10:12
 */


/**
 * 观察者模式
 */


/**
 * 抽象主题角色
 * Interface Subject
 */
interface Subject {

    /**
     * 增加一个新的观察者对象
     * @param Observer $observer
     * @return mixed
     */
    public function attach ( Observer $observer );


    /**
     * 删除一个已存在的观察者对象
     * @param Observer $observer
     * @return mixed
     */
    public function detach ( Observer $observer );


    /**
     * 通知所有注册过的观察者模式
     * @return mixed
     */
    public function notifyObservers ();
}


/**
 * 抽象观察者角色
 * Interface Observer
 */
interface Observer {

    /**
     * 更新方法
     * @return mixed
     */
    public function update ();
}


/**
 * 具体主题角色
 * Class ConcreteSubject
 */
class ConcreteSubject implements Subject {

    private $_observers;


    public function __construct () {
        $this->_observers = [];
    }


    /**
     * 增加一个新的观察者对象
     * @param Observer $observer
     * @return mixed
     */
    public function attach ( Observer $observer ) {
        // TODO: Implement attach() method.
        return array_push ( $this->_observers , $observer );
    }


    /**
     * 删除一个已存在的观察者对象
     * @param Observer $observer
     * @return mixed
     */
    public function detach ( Observer $observer ) {
        // TODO: Implement detach() method.
        $index = array_search ( $observer , $this->_observers );
        if ( $index === FALSE || ! array_key_exists ( $index , $this->_observers ) ) {
            return FALSE;
        }
        unset( $this->_observers[ $index ] );
        return TRUE;
    }


    /**
     * 通知所有注册过的观察者模式
     * @return mixed
     */
    public function notifyObservers () {
        // TODO: Implement notifyObservers() method.
        if ( ! is_array ( $this->_observers ) ) {
            return FALSE;
        }
        foreach ( $this->_observers as $ovserver ) {
            $ovserver->update ();
        }
        return TRUE;
    }
}


/**
 * 具体观察者角色
 * Class ConcreteObserver
 */
class ConcreteObserver implements Observer {

    private $_name;


    public function __construct ( $name ) {
        $this->_name = $name;
    }


    /**
     * 更新方法
     * @return mixed
     */
    public function update () {
        echo 'Observer' , $this->_name , "has notifed\r\n";
    }
}


//实例化类
$subject = new ConcreteSubject();

//添加第一个观察者
$observer1 = new ConcreteObserver( 'Martin' );
$subject->attach ( $observer1 );
echo '<br /> 第一次通知:<br />';
$subject->notifyObservers();


$observer2 = new ConcreteObserver( 'phppan' );
$subject->attach ( $observer2 );
echo '<br /> 第二次通知:<br />';
$subject->notifyObservers();
$subject->detach ( $observer1 );
echo '<br /> 第一次通知:<br />';
$subject->notifyObservers();

Laravel中实现

在Laravel中,我们可以用事件来实现这个功能,下篇文章就来具体通过Laravel的项目进行详细的讲解。




标签:
作者:猫巷

,

评论列表 (0)条评论

发表评论

召唤伊斯特瓦尔