设计模式-观察者模式

设计模式-观察者模式

说明

观察者模式(Observer),当一个对象的状态发生改变时,依赖他的对象会全部收到通知,并自动更新。


模式说明

场景:一个事件发生后,要执行一连串更新操作.传统的编程方式,就是在事件的代码之后直接加入处理逻辑,当更新的逻辑增多之后,代码会变得难以维护.这种方式是耦合的,侵入式的,增加新的逻辑需要改变事件主题的代码
观察者模式实现了低耦合,非侵入式的通知与更新机制

在PHP5.1之后,PHP提供了SPL(标准PHP库 - Standard PHP Library)这个库,这个库包括一组解决标准问题的接口和类其中就有观察者接口。

观察者模式的核心在于Subject和Observer 接口。Subject包含一个给定的状态,观察者"订阅"这个主题,将主题的当前状态通知观察者。可以认为它是一个博客,有很多订阅者,会定期地为订阅或定期阅读博客的各类用户更新一组信息。每次博客发生改变时(其状态改变),所有订阅者"都会得到通知"。

请输入图片描述

SplSubject {
/* 方法 */
abstract public attach ( SplObserver $observer ) : void    //附加SplObserver观察者
abstract public detach ( SplObserver $observer ) : void    //分离SplObserver观察者
abstract public notify ( void ) : void    //通知SplObserver观察者
}

SplObserver {
/* 方法 */
abstract public update ( SplSubject $subject ) : void    //接收被观察者更新
}

示例代码

<h5>场景说明</h5>
新用户注册之后,对新用户进行 初始话密码 和 发送短信接口操作

<h5>被观察者User类</h5>

//被观察者,用户注册之后 1.初始话密码 2.发送短信接口
//被观察者类必须实现SplSubject接口 且实现接口的  attach() detach() notify()方法

class User implements SplSubject {
    public $userName;
    public $phone;
    public $observers; //用来存储观察者对象

    public function __construct($userName,$phone)
    {
        $this->userName=$userName;
        $this->phone=$phone;
        $this->observers = new SplObjectStorage();//SplObjectStorage是SPL标准库中的数据结构对象容器,用来存储观察者对象
    }

    /**
     * @param SplObserver $observer
     * 添加观察者
     */
    public function attach(SplObserver $observer)
    {
        // TODO: Implement attach() method.
        $this->observers->attach($observer);
    }

    /**
     * @param SplObserver $observer
     * 移除观察者
     */
    public function detach(SplObserver $observer)
    {
        // TODO: Implement detach() method.
        $this->observers->detach($observer);
    }

    /**
     * 执行观察者操作
     */
    public function notify()
    {
        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
        // TODO: Implement notify() method.
    }
    //新用户注册流程 ,注册成功执行notify方法
    public function register(){
        //if(success)
        $this->notify();
    }

}

<h5>观察者类</h5>
观察者UserInit类和SendMessage类

//观察者 用户初始化类用来实现用户注册后的初始密码等操作
//观察者类必须实现SplObserver接口,并实现update() 方法
class UserInit implements  SplObserver {

    /**
     * @param SplSubject $subject
     */
    public function update(SplSubject $subject)
    {
        echo "用户".$subject->userName."的初始密码为:".mt_rand(100000, 999999).PHP_EOL;
        // TODO: Implement update() method.
    }
}

//观察者 发送短信类用来实现用户注册后的将用用户的信息发送给用户
//观察者类必须实现SplObserver接口,并实现update() 方法
class SendMessage implements  SplObserver {
    /**
     * @param SplSubject $subject
     */
    public function update(SplSubject $subject)
    {
        echo "已经向用户".$subject->userName."手机号".$subject->phone."发送短信".PHP_EOL;
        // TODO: Implement update() method.
    }
}

<h5>测试</h5>

header('Content-Type: text/plain');

$user=new User("zhangsan","17600128056");
$user->attach(new UserInit());
$user->attach(new SendMessage());
//用户
$user->register();

<h5>结果</h5>

浏览器输出结果:
用户zhangsan的初始密码为:620834
已经向用户zhangsan手机号17600128056发送短信

结尾

心如花木,向阳而生。

添加新评论