摘要:我們應該寫一段拓展性強與維護性較強的代碼,由此衍生出觀察者模式。
該文章屬于《編程中的那些經典套路——設計模式匯總》系列,并且以下內容基于語言PHP
今天我們來談談觀察者模式,這是一個經常用到的設計模式。
讓我們想象一個場景:一個網站有不同等級區域的用戶,不同等級的的用戶登錄后可以獲得對應的服務(一級用戶登錄后獲得一級服務,二級用戶登錄后獲得二級服務,…以此類推)。那么我們如何寫這段業務邏輯呢?
按照一般思路:我們會寫N個if..else判斷,像下面這樣:
//登錄操作..省略 if(一級用戶) { echo " 一級服務"; } else if(二級用戶){ echo "二級服務"; } else if(三級用戶){ echo "三級服務"; }
但這樣寫代碼有一個弊端,如果我們又增加了一個等級用戶,那么我們是不是要修改原來的代碼呢(增加多一個if..else判斷),這樣做是非常不妥當的,因為寫好的代碼我們不應該碰它。
我們應該寫一段拓展性強與維護性較強的代碼,由此衍生出觀察者模式。
觀察者模式的大致思路是這樣的:有一個觀察者列表(A),有一個被觀察者列表(B),當B發生變化時,程序就會遍歷觀察者列表A,隨之執行對應的update操作,然后獲得想要的效果。語言表述可能比較難以理解,我們來看代碼吧。
PHP已經幫我們內置了一個觀察者模式的接口(The SplSubject interface),我們可以直接實現這個接口:
并且php還提供了一個存儲對象的class(即觀察者列表):
當然我們完全可以不使用這個類,可以用數組代替。
具體代碼:
觀察者模式.php
observers = new SplObjectStorage(); } //登錄 public function login(){ //登錄過程,省略 $this->notify(); } //添加觀察者 public function attach(SplObserver $observer){ $this->observers->attach($observer); } //剔除觀察者 public function detach(SplObserver $observer){ $this->observers->detach($observer); } //登陸后通知notify public function notify(){ $observers = $this->observers; //這段rewind不可或缺... 將節點指針指向第一位節點 $observers->rewind(); //當前節點存在 while($observers->valid()){ $observer = $observers->current();//獲取當前節點(即觀察者) $observer->update($this);//進行update犯法操作 $observers->next();//next 節點 } } } //observer User1Observers class User1Observers implements SplObserver { public function update(SplSubject $subject){ echo "我是一級用戶,請給我對應的一級服務"; } } //observer User2Observers class User2Observers implements SplObserver { public function update(SplSubject $subject){ echo "我是二級用戶,請給我對應的二級服務"; } } //observer CommenUserObservers class CommenUserObservers implements SplObserver { public function update(SplSubject $subject){ echo "我是普通用戶,請給我對應的普通服務"; } } //如果需要的話可以繼續增加或者減少用戶等級,絲毫不會影響原本的等級用戶 $subject = new LoginSubject(); $CommenUserObservers = new CommenUserObservers;//普通用戶 $subject->attach(new User1Observers);//增加觀察者:一級用戶 $subject->attach(new User2Observers);//增加觀察者:二級用戶 $subject->attach($CommenUserObservers);//增加觀察者:普通用戶 $subject->login();//登錄,觸發notify //output:我是一級用戶,請給我對應的一級服務我是二級用戶,請給我對應的二級服務我是普通用戶,請給我對應的普通服務 echo "
"; //如果有一天普通用戶壓根沒有對應的服務了,那么我們就可以剔除它了 //$subject->detach(new CommenUserObservers); 無效 $subject->detach($CommenUserObservers);//刪除觀察者:普通用戶 $subject->login();//登錄,觸發notify,普通用戶就不會被通知啦 //output:我是一級用戶,請給我對應的一級服務我是二級用戶,請給我對應的二級服務 ?>
看出門道了嗎?每當登錄操作的時候,就會順帶觸發notify方法,從而遍歷關注者列表內的對象方法update,從而達到不同的用戶獲得不同的服務目的,而當我們需要新增/減少用戶等級的時候又不需要修改源代碼,很好的符合了開放封閉原則。
我一直認為觀察者模式、單例模式、工廠模式三者都是很棒的設計模式,但觀察者模式理解起來稍微比較困難,如果有困惑的話可以直接在評論區發問。
該文章屬于《編程中的那些經典套路——設計模式匯總》系列
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/21671.html
該文章屬于《編程中的那些經典套路——設計模式匯總》系列,并且以下內容基于語言PHP 今天來談談責任鏈模式,乍一聽責任鏈模式好像很高級的一樣,但是相信我,其實每位天朝的同學都十分熟悉這個模式,責任鏈模式,就好像中國的官場制度一樣,每一個級別的權利都區分的很細,舉個生活中的栗子: 村委不能越級去替鎮委辦事情,如果村委無法解決,只能向上求助鎮委 鎮委不能越級去替市委辦事情,如果鎮委無法解決,只能向上求...
摘要:如果看不懂的話,可以在評論區中提問,我會第一時間回答你無論何時我一直都在嗯哼該文章屬于編程中的那些經典套路設計模式匯總系列 在正式閱讀前,我先談談我們該用什么姿勢和心態學習設計模式: 如果你還沒有過多的編程經驗(泛指半年以下),我建議你把它當做小說來看,能看懂多少是多少,因為半年以下經驗的程序員用到設計模式的情況只會出現在面試上,至于實際工作中?相對來說這部分不會由你負責。 如果你已...
摘要:該文章屬于編程中的那些經典套路設計模式匯總系列,并且以下內容基于語言前面我們寫了簡單工廠模式,編程中的那些套路關于簡單工廠模式,但簡單工廠模式有一些不足違反開放封閉原則,所以需要設計出一套更加規范的設計模式。 該文章屬于《編程中的那些經典套路——設計模式匯總》系列,并且以下內容基于語言PHP 前面我們寫了簡單工廠模式,《編程中的那些套路——關于簡單工廠模式》,但簡單工廠模式有一些不足(...
摘要:簡單工廠模式就是遵循了這一原則,它讓不同職責的類各司其職。重點來了,簡單工廠模式的不足但是簡單工廠模式有一個不足,雖然它遵循了單一職責原則,但它違反了另一條同樣很重要的原則開放封閉原則。 該文章屬于《編程中的那些經典套路——設計模式匯總》系列,并且以下內容基于語言PHP 面向對象五大原則中有一點非常重要的原則:單一職責原則。 簡單工廠模式就是遵循了這一原則,它讓不同職責的類各司其職。 ...
該文章屬于《編程中的那些經典套路——設計模式匯總》系列,并且以下內容基于語言PHP 在設計模式中,單例模式和工廠模式)可以說是使用的最普遍的設計模式了,所以掌握此種模式尤為重要。 單例模式一般使用在資源共享和需要控制資源的情況下。 例如:購物車,回收站,數據庫連接池,計數器,配置文件共享等所有項目中只需要存在一個的模塊,你都可以采用單例模式。 單例模式的好處就在于當前進程只產生一個對象(或者叫...
閱讀 834·2019-08-30 14:05
閱讀 1724·2019-08-30 11:08
閱讀 3226·2019-08-29 15:41
閱讀 3602·2019-08-23 18:31
閱讀 1523·2019-08-23 18:29
閱讀 557·2019-08-23 14:51
閱讀 2115·2019-08-23 13:53
閱讀 2135·2019-08-23 13:02