摘要:設(shè)計(jì)觀察者模式是為了讓一個(gè)對(duì)象跟蹤某個(gè)狀態(tài),知道狀態(tài)何時(shí)改變,一旦狀態(tài)改變,所有訂閱對(duì)象都能得到通知。類與觀察者設(shè)計(jì)模式?jīng)]有內(nèi)在的關(guān)系,不過(guò)通過(guò)它其內(nèi)置的和方法可以很方便的將觀察者實(shí)例與一個(gè)主題實(shí)例相關(guān)聯(lián)以及解除關(guān)聯(lián)。
前言
知識(shí)就是作為觀察者所獲得的結(jié)論,經(jīng)過(guò)科學(xué)培訓(xùn)的觀察者會(huì)為我們提供所有能感知的現(xiàn)實(shí)。設(shè)計(jì)觀察者模式是為了讓一個(gè)對(duì)象跟蹤某個(gè)狀態(tài),知道狀態(tài)何時(shí)改變,一旦狀態(tài)改變,所有訂閱對(duì)象都能得到通知。如果需要保證一個(gè)狀態(tài)的一致性(比如說(shuō):狀態(tài)觸發(fā)類的應(yīng)用),但是這個(gè)給定狀態(tài)可能有多個(gè)不同的用戶等級(jí),這種情況下觀察者模式就很適用,而且很有幫助,各司其職。利用觀察者模式可以維護(hù)一致性,同時(shí)記錄創(chuàng)建一個(gè)給定的狀態(tài)的對(duì)象個(gè)數(shù)。
觀察者模式很直觀。何必讓多個(gè)對(duì)象創(chuàng)建或跟蹤一個(gè)給定的狀態(tài)呢?如果由一個(gè)對(duì)象完成這個(gè)工作,然后通知其他可能用到這個(gè)狀態(tài)的對(duì)象,這樣會(huì)合理得多。
使用SPL實(shí)現(xiàn)觀察者模式1、可用于觀察者設(shè)計(jì)模式的3個(gè)SPL接口/類如下:
● SplSubject
● SplObserver
● SplObjectStorage
1.1、SplSubject
注意這個(gè)SplSubject 接口指定attach()和detach()方法參數(shù)中$observer的數(shù)據(jù)類型必須是一個(gè)SplObserver 對(duì)象。
1.2、SplObserver
SplObserver 接口只有一個(gè)update()方法,如下所示:
update()方法對(duì)于觀察者模式至關(guān)重要,因?yàn)樗鼤?huì)得到Subject狀態(tài)的最新變化,并交給觀察者實(shí)例。
1.3、SplObjectStorage
SplObjectStorage 類與觀察者設(shè)計(jì)模式?jīng)]有內(nèi)在的關(guān)系,不過(guò)通過(guò)它其內(nèi)置的attach()和detach()方法可以很方便的將觀察者實(shí)例與一個(gè)主題實(shí)例相關(guān)聯(lián)以及解除關(guān)聯(lián)。
storage[] = $observer; } //刪除方法 public function detach(SplObserver $observer) { if(is_int($idx = array_search($observer, $this->storage))) { unset($this->storage[$idx]); } } }注釋:如果直接用PHP類庫(kù)的SplObjectStorage類的話,1.3可以不看了,只需要把1.4里面的$this->observers = new SplObjectStorage();修改為$this->observers = new SplObjectStorage();(原因可以去了下PHP的解命名空間和文件加載機(jī)制。參考資料),notify方法里的$this->observers->storage修改為$this->observers即可。
1.4、SPL具體主題
SplSubject接口不包括獲取方法和設(shè)置方法,不過(guò)這也是觀察者設(shè)計(jì)模式中的一部分,所以需要增加獲取方法和設(shè)置方法。設(shè)置方法setData()包含一個(gè)參數(shù),這是要增加的任何類型的數(shù)據(jù)。獲取方法getData()存儲(chǔ)當(dāng)前的主題狀態(tài),由具體觀察者用來(lái)更新觀察者數(shù)據(jù)。
另外還增加了setObservers()方法。并不是在構(gòu)造函數(shù)中設(shè)置SplObjectStorage()實(shí)例,也沒(méi)有在setData()方法中設(shè)置觀察者實(shí)例,這里實(shí)現(xiàn)了一個(gè)多帶帶的setObservers()方法,可以提供更輕松的耦合,并允許有多組觀察者。observers = new SplObjectStorage(); } //添加觀察者 public function attach(SplObserver $observer) { $this->observers->attach($observer); } //剔除觀察者 public function detach(SplObserver $observer) { $this->observers->detach($observer); } //通知notify public function notify() { foreach ($this->observers->storage as $key =>$observer) { $observer->update($this); } } //設(shè)置方法 public function setData($dataNow) { $this->data=$dataNow; } //獲取方法 public function getData() { return $this->data; } } ?>1.5、SPL具體觀察者
用于實(shí)現(xiàn)更新函數(shù)來(lái)更新關(guān)聯(lián)的觀察者實(shí)例。
getData().""; } } ?>(附加的普通用戶具體觀察者)
1.6、SPL客戶
“SPL”Client 類只是一個(gè)標(biāo)準(zhǔn)客戶。這個(gè)客戶按照SPL接口向具體主題和觀察者發(fā)出多個(gè)請(qǐng)求,不過(guò)自己并沒(méi)有實(shí)現(xiàn)SPL類和接口。
創(chuàng)造新的具體觀察者,新的具體主體:"; $ob1 = new ConcreteObserver(); $ob2 = new ConcreteObserver(); $ob3 = new ConcreteObserver(); $Subject = new ConcreteSubject(); $Subject->setObservers(); $Subject->setData("這是你的數(shù)據(jù)!"); $Subject->attach($ob1); $Subject->attach($ob2); $Subject->attach($ob3); $Subject->notify(); echo "刪除ob3,結(jié)果是ob1和ob2的通知:
"; $Subject->detach($ob3); $Subject->notify(); echo "剩余的數(shù)據(jù)和附加數(shù)據(jù)還有刪除ob2,結(jié)果是ob1和ob3的通知:
"; $Subject->setData("更多的數(shù)據(jù),只有ob1和ob3是需要的"); $Subject->attach($ob3); $Subject->detach($ob2); $Subject->notify(); echo "剩余數(shù)據(jù)和附加新數(shù)據(jù),結(jié)果是ob1和ob3還有“新數(shù)據(jù)”的通知:
"; $Subject->attach(new commonobserverUserObserver); $Subject->notify(); } } ?>1.7、Client的調(diào)用輸出如下:
調(diào)用:$worker=new commonobserverClient();
輸出:
總結(jié)分析這里SplObjectStorage類是我自己寫的,貼出來(lái)分享一下。PHP5.1.0以及更高的版本有很多特性,其中之一就是提供了一組可以用于觀察者的設(shè)計(jì)模式的接口。可以研究一下怎么使用,SplObserver接口以及SplSubject和SplObjectStorage接口,利用這些接口,構(gòu)建觀察者模式簡(jiǎn)直易如反掌?!癝PL”是標(biāo)準(zhǔn)PHP類庫(kù)(Standard PHP Library)的簡(jiǎn)寫,這個(gè)庫(kù)中包括一組解決標(biāo)準(zhǔn)問(wèn)題的接口和類。參考手冊(cè)
相關(guān)資料關(guān)于觀察者模式
利用 SPL 快速實(shí)現(xiàn) Observer 設(shè)計(jì)模式
PHP SPL標(biāo)準(zhǔn)庫(kù)之?dāng)?shù)據(jù)結(jié)構(gòu)對(duì)象容器(SplObjectStorage)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/81231.html
摘要:概念觀察者模式屬于行為模式,是定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,以便當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并自動(dòng)刷新。觀察者模式符合接口隔離原則,實(shí)現(xiàn)了對(duì)象之間的松散耦合。 概念 觀察者模式屬于行為模式,是定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,以便當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并自動(dòng)刷新。 當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變后,會(huì)影響到其他幾個(gè)對(duì)象的改變,這...
摘要:設(shè)計(jì)觀察者模式是為了讓一個(gè)對(duì)象跟蹤某個(gè)狀態(tài),知道狀態(tài)何時(shí)改變,一旦狀態(tài)改變,所有訂閱對(duì)象都能得到通知。類與觀察者設(shè)計(jì)模式?jīng)]有內(nèi)在的關(guān)系,不過(guò)通過(guò)它其內(nèi)置的和方法可以很方便的將觀察者實(shí)例與一個(gè)主題實(shí)例相關(guān)聯(lián)以及解除關(guān)聯(lián)。 前言 知識(shí)就是作為觀察者所獲得的結(jié)論,經(jīng)過(guò)科學(xué)培訓(xùn)的觀察者會(huì)為我們提供所有能感知的現(xiàn)實(shí)。設(shè)計(jì)觀察者模式是為了讓一個(gè)對(duì)象跟蹤某個(gè)狀態(tài),知道狀態(tài)何時(shí)改變,一旦狀態(tài)改變,所有...
摘要:設(shè)計(jì)觀察者模式是為了讓一個(gè)對(duì)象跟蹤某個(gè)狀態(tài),知道狀態(tài)何時(shí)改變,一旦狀態(tài)改變,所有訂閱對(duì)象都能得到通知。類與觀察者設(shè)計(jì)模式?jīng)]有內(nèi)在的關(guān)系,不過(guò)通過(guò)它其內(nèi)置的和方法可以很方便的將觀察者實(shí)例與一個(gè)主題實(shí)例相關(guān)聯(lián)以及解除關(guān)聯(lián)。 前言 知識(shí)就是作為觀察者所獲得的結(jié)論,經(jīng)過(guò)科學(xué)培訓(xùn)的觀察者會(huì)為我們提供所有能感知的現(xiàn)實(shí)。設(shè)計(jì)觀察者模式是為了讓一個(gè)對(duì)象跟蹤某個(gè)狀態(tài),知道狀態(tài)何時(shí)改變,一旦狀態(tài)改變,所有...
摘要:我們今天也來(lái)做一個(gè)萬(wàn)能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...
摘要:我們今天也來(lái)做一個(gè)萬(wàn)能遙控器設(shè)計(jì)模式適配器模式將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。今天要介紹的仍然是創(chuàng)建型設(shè)計(jì)模式的一種建造者模式。設(shè)計(jì)模式的理論知識(shí)固然重要,但 計(jì)算機(jī)程序的思維邏輯 (54) - 剖析 Collections - 設(shè)計(jì)模式 上節(jié)我們提到,類 Collections 中大概有兩類功能,第一類是對(duì)容器接口對(duì)象進(jìn)行操作,第二類是返回一個(gè)容器接口對(duì)象,上節(jié)我們介紹了...
閱讀 2741·2021-11-22 15:22
閱讀 1653·2021-11-22 14:56
閱讀 3629·2021-09-22 15:12
閱讀 2415·2021-09-02 15:41
閱讀 2139·2021-08-27 16:26
閱讀 1126·2019-08-30 15:55
閱讀 2151·2019-08-29 17:30
閱讀 679·2019-08-29 16:26