在之前的文章《一文了解PHP中的適配器模式》中我們介紹了PHP中的適配器模式,以下這篇文章帶大家了解一下PHP中的觀察者模式。
觀察者,似乎在許多科幻作品中都會有這個角色的出現。例如我很喜歡的一部美劇《危機邊緣》,在這個劇集中,觀察者不停的穿越時空記錄著各種各樣的人或事。但是,設計模式中的觀察者可不只是站在邊上看哦,這裡的觀察者是針對主體所發生的狀態改變來做出對應的動作。
Gof類別圖與解釋
GoF定義:定義物件間的一種一對多的依賴關係,當一個物件的狀態當改變發生時,所有依賴它的物件都會被通知並被自動更新
#GoF類別圖:
程式碼實作
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中的發布訂閱及事件監聽方面的內容。
訂單售出類別圖
#完整原始碼: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中文網其他相關文章!

PHP在現代Web開發中仍然重要,尤其在內容管理和電子商務平台。 1)PHP擁有豐富的生態系統和強大框架支持,如Laravel和Symfony。 2)性能優化可通過OPcache和Nginx實現。 3)PHP8.0引入JIT編譯器,提升性能。 4)雲原生應用通過Docker和Kubernetes部署,提高靈活性和可擴展性。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

記事本++7.3.1
好用且免費的程式碼編輯器

Atom編輯器mac版下載
最受歡迎的的開源編輯器