1. 程式人生 > >PHP 觀察者模式 理解

PHP 觀察者模式 理解

用模式開發的優點是,能讓我們的邏輯結構以及程式碼更加清晰,便於維護!

而我們為什麼要用 “觀察者模式”?這就需要從實際運用中來理解才能更好的運用!用如下的情境來說明吧。

事例,開始時我被安排做專案的登入,很快我就完成了。然後產品提出了另一個需求,使用者登入後,給他們推送一條實時訊息!然後我在登入成功的邏輯後加了一段程式碼,完成了登入後的實時訊息推送。然而事情還沒有完,產品又給加了個需求,需要給新登入的使用者10塊錢紅包獎勵,這個當然很簡單,我又在訊息推送後加了程式碼,完成了新登入使用者的紅包獎勵(錢怎麼到賬的過程暫且不論),然而事情還沒完沒了了,產品不斷的在加需求了,如非vip使用者登入,給他推送10條需要註冊VIP才能開啟的資訊,如根據客戶習慣推送10條客戶偏好的資訊,如vip快到期的客戶需要在客戶登入後提醒要充值啦。。。。。。。等等,如是這般,那我就得不停的在登入後加程式碼,變得我開始看不懂哪個xxx寫的程式碼了!

那麼此時我們就得考慮用‘觀察者模式’了

可以以這樣的方式簡單明瞭形容 觀察者模式, 某個商場門口安排一個人進行觀察,觀察到有a型別的顧客進門,立即安排敲鑼、打鼓、送鮮花,觀察到有b類客戶,立即安排購物袋,觀察到c類客戶,嗯嗯感覺他是來打醬油了,安排不要浪費表情了,什麼歡迎儀式也沒有。。。。。也就是說 觀察者就是個‘勢利眼’,看人下彩,根據觀察給進來的顧客安排對應的某個服務或者某些服務!也許這個形容還不夠恰當,但大體意思差不多了。

接下來就是重點了,描述了觀察者模式的輪廓,那麼就需要轉化為程式碼來實際運用了!

一、首先得有兩個介面類,用以框定觀察者模式,

        一個被觀察者介面類(一般申明有三個必須方法:1.新增觀察者物件的方法,2.刪除觀察者物件的方法 ,3.通知觀察者進行  相應執行的方法),

        一個觀察者介面類(一般只有一個必須方法,就是執行)

如果直接甩程式碼可能有點難理解,那麼就先給個示意圖來明確一下吧!

二、根據觀察者介面類的框定我們定下介面類如下程式碼:

(示例是網上抄的,因為易於理解,申明一下出處,網址:https://www.cnblogs.com/DeanChopper/p/4830134.html):

<?php
// 被觀察者介面
interface Subject{
    public function register(Observer $observer);  //新增(註冊)觀察者物件
    public function detach(Observer $observer);    //刪除觀察者物件
    public function notify();                      //通知觀察者執行相應功能
}
// 觀察者介面
interface Observer{
    public function watch();   //觀察者要執行的方法
}

三、根據框定的結構,大概的理解一下就是,要實現 被觀察者物件 儲存各種觀察者物件(完成各種功能的物件)儲存起來,然後通只各觀察者執行自己的功能,先看看如下的實現程式碼

<?php
// 被觀察者繼承類
class Action implements Subject{

     public $_observers=array(); //用於儲存觀察者物件

     //用於新增(註冊)觀察者物件
     public function register(Observer $observer){
         $this->_observers[]=$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 notify(){

         //****重點,其實就是迴圈中執行各觀察這物件的watch方法,不同功能方法內容不同但方法名相同
         foreach ($this->_observers as $observer) {
             $observer->watch();
         }

     }
 }

// cat觀察者繼承類
class Cat implements Observer{
     public function watch(){
         echo "Cat watches TV<hr/>";
     }
 } 

 //dog觀察者繼承類
 class Dog implements Observer{
     public function watch(){
         echo "Dog watches TV<hr/>";
     }
 } 
 //people觀察者繼承類
 class People implements Observer{
     public function watch(){
         echo "People watches TV<hr/>";
     }
 }

好了,我們現在通過上面的繼承就能明白了,觀察者就是定義各種功能的物件(這些物件就是:比如給第一次登入的使用者發紅包,給使用者最新的10條文章推送,給非vip使用者推送10條需要註冊才能開啟的視訊誘導使用者開通vip。。。。),被觀察者物件要實現的就是 將新增(註冊)的觀察者物件儲存起來並逐個通知執行觀察者各自的功能,

四、那麼就進行例項化物件進行操作了!程式碼如下:

// 應用例項
$action=new Action();
$action->register(new Cat());
$action->register(new People());
$action->register(new Dog());
$action->notify();

到這裡我想如果應該是有所理解了,如果我的理解有誤請提建議,當然這只是觀察者模式的一個簡單過程,實際開發中會有所改動,當然大體脈絡就是這樣的!

還有一點個人的觀點是,如果我們需要搞清楚各種開發模式運用,那麼就要從它能解決的需求理解,面向物件程式設計它是來源於生活,應用於生活的,從這種模式解決的需求上進行理解,然後我們才能明白架構定義出來的程式碼(說得玄一點就是將 想法轉化為程式碼來實現,通過程式碼 得到我們想要的結果) 。寫下這些其實也不為其他,只是想加深自己的印象,同時也希望對其他 同行的朋友有所助益!