首頁 php教程 php手册 PHP设计模式之观察者模式示例介绍

PHP设计模式之观察者模式示例介绍

Jun 13, 2016 am 09:39 AM
php 主要 介紹 文章 模式 範例 設計模式

 这篇文章主要介绍了PHP设计模式之观察者模式(Observer)详细介绍和代码实例,需要的朋友可以参考下

【意图】

 

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新【GOF95】 又称为发布-订阅(Publish-Subscribe)模式、模型-视图(Model-View)模式、源-监听(Source-Listener)模式、或从属者(Dependents)模式

 

【观察者模式结构图】

 

 

 

【观察者模式中主要角色】

 

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

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

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

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

 

【观察者模式的优点和缺点】

 

观察者模式的优点:

 

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

2.支持广播通信;

 

观察者模式的缺点:

 

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

 

 

【观察者模式适用场景】

 

当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。

当对一个对象的改变需要同时改变其它对象,而不知道具体有多少个对象待改变。

当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换句话说,你不希望这些对象是紧密耦合的。

 

【观察者模式与其它模式】

 

1.中介者模式(Mediator):通过封装复杂的更新语义,ChangeManager充当目标和观察者之间的中介者。

2.单例模式(singleton模式):ChangeManager可使用Singleton模式来保证它是唯一的并且是可全局访问的。

 

 

【观察者模式PHP示例】

 代码如下:

 

/**

* 观察者模式

* @package design pattern

*/

 

/**

* 抽象主题角色

*/

interface Subject {

 

    /**

     * 增加一个新的观察者对象

     * @param Observer $observer

     */

    public function attach(Observer $observer);

 

    /**

     * 删除一个已注册过的观察者对象

     * @param Observer $observer

     */

    public function detach(Observer $observer);

 

    /**

     * 通知所有注册过的观察者对象

     */

    public function notifyObservers();

}

 

/**

* 具体主题角色

*/

class ConcreteSubject implements Subject {

 

    private $_observers;

 

    public function __construct() {

        $this->_observers = array();

    }

 

    /**

     * 增加一个新的观察者对象

     * @param Observer $observer

     */

    public function attach(Observer $observer) {

        return array_push($this->_observers, $observer);

    }

 

    /**

     * 删除一个已注册过的观察者对象

     * @param Observer $observer

     */

    public function detach(Observer $observer) {

        $index = array_search($observer, $this->_observers);

        if ($index === FALSE || ! array_key_exists($index, $this->_observers)) {

            return FALSE;

        }

 

        unset($this->_observers[$index]);

        return TRUE;

    }

 

    /**

     * 通知所有注册过的观察者对象

     */

    public function notifyObservers() {

        if (!is_array($this->_observers)) {

            return FALSE;

        }

 

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

            $observer->update();

        }

 

        return TRUE;

    }

 

}

 

/**

* 抽象观察者角色

*/

interface Observer {

 

    /**

     * 更新方法

     */

    public function update();

}

 

class ConcreteObserver implements Observer {

 

    /**

     * 观察者的名称

     * @var

     */

    private $_name;

 

    public function __construct($name) {

        $this->_name = $name;

    }

 

    /**

     * 更新方法

     */

    public function update() {

        echo 'Observer', $this->_name, ' has notified.
';

    }

 

}

实例化类:

$subject = new ConcreteSubject();

 

/* 添加第一个观察者 */

$observer1 = new ConcreteObserver('Martin');

$subject->attach($observer1);

 

echo '
The First notify:
';

$subject->notifyObservers();

 

/* 添加第二个观察者 */

$observer2 = new ConcreteObserver('phppan');

$subject->attach($observer2);

 

echo '
The Second notify:
';

$subject->notifyObservers();

 

/* 删除第一个观察者 */

$subject->detach($observer1);

 

echo '
The Third notify:
';

$subject->notifyObservers();

具体案例:

 

 /**  

  * 3.1php设计模式-观测者模式  

  * 3.1.1概念:其实观察者模式这是一种较为容易去理解的一种模式吧,它是一种事件系统,意味  

  *          着这一模式允许某个类观察另一个类的状态,当被观察的类状态发生改变的时候,  

  *          观察类可以收到通知并且做出相应的动作;观察者模式为您提供了避免组件之间

  *          紧密耦合的另一种方法

  * 3.1.2关键点:

  *        1.被观察者->追加观察者;->一处观察者;->满足条件时通知观察者;->观察条件

  *        2.观察者 ->接受观察方法

  * 3.1.3缺点:

  * 3.1.4观察者模式在PHP中的应用场合:在web开发中观察者应用的方面很多

  *        典型的:用户注册(验证邮件,用户信息激活),购物网站下单时邮件/短信通知等

  * 3.1.5php内部的支持

  *        SplSubject 接口,它代表着被观察的对象,

  *        其结构:

  *        interface SplSubject

  *        {

  *            public function attach(SplObserver $observer);

  *            public function detach(SplObserver $observer);

  *            public function notify();

  *        }

  *        SplObserver 接口,它代表着充当观察者的对象,

  *        其结构:

  *        interface SplObserver

  *        {   

  *            public function update(SplSubject $subject);

  *        }

  */

 

 /**

  * 用户登陆-诠释观察者模式

  */

class User implements SplSubject {

    //注册观察者

    public $observers = array();

 

    //动作类型

    CONST OBSERVER_TYPE_REGISTER = 1;//注册

    CONST OBSERVER_TYPE_EDIT = 2;//编辑

 

    /**

     * 追加观察者

     * @param SplObserver $observer 观察者

     * @param int $type 观察类型

     */

    public function attach(SplObserver $observer, $type)

    {

        $this->observers[$type][] = $observer;

    }

 

    /**

     * 去除观察者

     * @param SplObserver $observer 观察者

     * @param int $type 观察类型

     */

    public function detach(SplObserver $observer, $type)

    {

        if($idx = array_search($observer, $this->observers[$type], true))

        {

            unset($this->observers[$type][$idx]);

        }

    }

 

    /**

     * 满足条件时通知观察者

     * @param int $type 观察类型

     */

    public function notify($type)

    {

        if(!empty($this->observers[$type]))

        {

            foreach($this->observers[$type] as $observer)

            {

                $observer->update($this);

            }

        }

    }

 

    /**

     * 添加用户

     * @param str $username 用户名

     * @param str $password 密码

     * @param str $email 邮箱

     * @return bool

     */

    public function addUser()

    {

 

        //执行sql

 

        //数据库插入成功

        $res = true;

 

        //调用通知观察者

        $this->notify(self::OBSERVER_TYPE_REGISTER);

 

        return $res;

    }

 

    /**

     * 用户信息编辑

     * @param str $username 用户名

     * @param str $password 密码

     * @param str $email 邮箱

     * @return bool

     */

    public function editUser()

    {

 

        //执行sql

 

        //数据库更新成功

        $res = true;

 

        //调用通知观察者

        $this->notify(self::OBSERVER_TYPE_EDIT);

 

        return $res;

    }

}

 

/**

* 观察者-发送邮件

*/

class Send_Mail implements SplObserver

 {

    /**

     * 相应被观察者的变更信息

     * @param SplSubject $subject

     */

    public function update(SplSubject $subject)

    {

        $this->sendMail($subject->email, $title, $content);

    }

 

    /**

     *发送邮件

     *@param str $email 邮箱地址

     *@param str $title 邮件标题

     *@param str $content 邮件内容

     */

    public function sendEmail($email, $title, $content)

    {

        //调用邮件接口,发送邮件

    }

}

?>

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

我後悔之前不知道的 7 個 PHP 函數 我後悔之前不知道的 7 個 PHP 函數 Nov 13, 2024 am 09:42 AM

如果您是經驗豐富的PHP 開發人員,您可能會感覺您已經在那裡並且已經完成了。操作

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

See all articles