目錄
Gof類別圖與解釋
#實例
首頁 後端開發 php教程 深入淺析PHP中的觀察者模式

深入淺析PHP中的觀察者模式

Jun 30, 2021 pm 07:43 PM
php 觀察者模式 設計模式

在之前的文章《一文了解PHP中的適配器模式》中我們介紹了PHP中的適配器模式,以下這篇文章帶大家了解一下PHP中的觀察者模式。

深入淺析PHP中的觀察者模式

觀察者,似乎在許多科幻作品中都會有這個角色的出現。例如我很喜歡的一部美劇《危機邊緣》,在這個劇集中,觀察者不停的穿越時空記錄著各種各樣的人或事。但是,設計模式中的觀察者可不只是站在邊上看哦,這裡的觀察者是針對主體所發生的狀態改變來做出對應的動作。

Gof類別圖與解釋

GoF定義:定義物件間的一種一對多的依賴關係,當一個物件的狀態當改變發生時,所有依賴它的物件都會被通知並被自動更新

#GoF類別圖:

深入淺析PHP中的觀察者模式

程式碼實作

interface Observer
{
    public function update(Subject $subject): void;
}
登入後複製

觀察者的抽象接口,沒啥可說的吧,就是讓你實作一個具體的Update就可以了

class ConcreteObserver implements Observer
{
    private $observerState = '';
    function update(Subject $subject): void
    {
        $this->observerState = $subject->getState();
        echo '执行观察者操作!当前状态:' . $this->observerState;
    }
}
登入後複製

具體的觀察者,實作update()方法,這裡我們拿到了Subject類,從而可以獲得其中的狀態

class Subject
{
    private $observers = [];
    private $stateNow = '';
    public function attach(Observer $observer): void
    {
        array_push($this->observers, $observer);
    }
    public function detach(Observer $observer): void
    {
        $position = 0;
        foreach ($this->observers as $ob) {
            if ($ob == $observer) {
                array_splice($this->observers, ($position), 1);
            }
            ++$position;
        }
    }
    public function notify(): void
    {
        foreach ($this->observers as $ob) {
            $ob->update($this);
        }
    }
}
登入後複製

Subject父類,維護一個觀察者數組,然後有添加、刪除以及循環遍歷這個數組的方法,目的是能夠方便的管理所有的觀察者

class ConcreteSubject extends Subject{
    public function setState($state)
    {
        $this->stateNow = $state;
        $this->notify();
    }

    public function getState()
    {
        return $this->stateNow;
    }
}
登入後複製

Subject的實現類,只是更新了狀態,在這個狀態發生改變的時候,調用觀察者遍歷的方法進行所有觀察的update ()操作

  • 觀察者,其實就是自身做了一個更新(update),而Subject,可以批量的執行觀察者,請注意,我們不需要去修改目標類別中的任何程式碼,只需要從外部添加就可以了,所以就讓目標和觀察者解耦互相之間不用關心對方的情況了
  • 觀察者可以記錄目標的狀態,也可以不用記錄,比如我們發完簡訊後的資料庫更新或插入操作,只有簡訊介面發送成功後我們再修改簡訊資料的狀態就可以了,不一定完全需要將目標的傳送狀態傳送給觀察者
  • 當一個類別在當改變發生時,不知道可能會對其他多少類別產生影響,這個時候觀察者非常有用
  • 觀察者模式中還是存在著耦合,那就是目標類別中有一個觀察者物件列表,如果觀察者沒有實現update()方法,那麼就會出現問題

接著拿我們的手機工廠說事兒,這次好嘛,被一群山寨機盯上了(觀察者),我出什麼功能(狀態更新),他們就對應的出一樣的功能(更新),而且還在我的基礎上做了更多的東西,美其名曰:微創新!你說氣人不氣人。好吧,我也派出了一群市場調查人員(觀察者),去幫我觀察別人家的手機都出了什麼功能(狀態更新),然後我們也照搬過來搞點微創新,大家共同進步嘛! !

完整程式碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/06.observer/source/observer.php

#實例

這次我們從訂單說起,不過還是有簡訊發送的事兒。當一般的電商平台有人下單之後,需要做的事情非常多,例如修改庫存、發送簡訊或推送告訴商家有人下單了,告訴買家下單成功了,支付成功了。總之就是一件事情的發生會導致各種事件的產生。其實,這裡就引出了另一個非常有名的模式訂閱發布模式。這個模式可以說是觀察者的升級模式,這個系列的文章不會細講,但是大家可以去看看Laravel中的發布訂閱事件監聽方面的內容。

訂單售出類別圖

深入淺析PHP中的觀察者模式

#完整原始碼:https://github.com/zhangyue0503/designpatterns- php/blob/master/06.observer/source/order-observer.php

interface Observer
{
    public function update($obj);
}

class Message implements Observer
{
    //....

    function update($obj)
    {
        echo '发送新订单短信(' . $obj->mobile . ')通知给商家!';
    }

    //....
}

class Goods implements Observer
{
    //....

    public function update($obj)
    {
        echo '修改商品' . $obj->goodsId . '的库存!';
    }

    //....
}

class Order
{
    private $observers = [];
    public function attach($ob)
    {
        $this->observers[] = $ob;
    }

    public function detach($ob)
    {
        $position = 0;
        foreach ($this->observers as $ob) {
            if ($ob == $observer) {
                array_splice($this->observers, ($position), 1);
            }
            ++$position;
        }
    }
    public function notify($obj)
    {
        foreach ($this->observers as $ob) {
            $ob->update($obj);
        }
    }
    public function sale()
    {
        // 商品卖掉了
        // ....
        $obj = new stdClass();
        $obj->mobile = '13888888888';
        $obj->goodsId = 'Order11111111';
        $this->notify($obj);
    }
}

$message = new Message();
$goods = new Goods();
$order = new Order();
$order->attach($message);
$order->attach($goods);

// 订单卖出了!!
$order->sale();
登入後複製

說明

  • 我們沒有完全的遵守GoF類別圖,雖說GoF是聖經,但也並不是我們必須要完全遵守的,我們可以針對具體的業務情況進行合適的裁剪使用
  • 訂單狀態透過sale()方法產生變化後,直接呼叫notify方法進行觀察者的呼叫
  • 發送簡訊、發推都可以拆開由一個一個的觀察者來實現,這些觀察者不一定只有這一個方法,但只要實現共同的接口就可以了
  • 商品庫存和消息發送其實就是兩個本身完全不沾邊的類,但它們只需要實現一樣的接口就好啦
  • PHP的SPL擴展中已經為我們準備好了一套觀察者接口,大家可以試試哦,使用原生支持的觀察者模式能省不少事兒呢!

SPL擴充實作觀察者模式-完整原始碼:https://github.com/zhangyue0503/designpatterns-php/blob/master/06.observer/source/spl_observer.php

本文轉載自:https://juejin.cn/post/6844903930262978574

作者:硬核心專案經理

推薦學習: 《PHP影片教學

以上是深入淺析PHP中的觀察者模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡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脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++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

如何設定 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中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

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

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 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.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

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

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

解釋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