淺談設計模式之觀察者模式

悲劇不上演發表於2018-01-25

觀察者模式:定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並被自動更新 又稱為釋出-訂閱(Publish-Subscribe)模式、模型-檢視(Model-View)模式、源-監聽(Source-Listener)模式、或從屬者(Dependents)模式。


應用場景:當我們在亞馬遜下一個訂單,這時候我們的郵箱會收到一封郵件,商家的郵箱也有收到一封郵件,我們的程式碼會如下:


class Order{
    public function register(){
        //TO-DO 下訂單
        echo "下訂單完成";
        //訂單完成之後操作
        echo "給使用者發郵件";
        echo "給商戶發郵件";
        //TO-DO 其他事
    }
}

當我們的業務慢慢的變複雜。可能裡面會有許多許多邏輯程式碼,然而每一次增加功能,都需對原來程式碼進行修改,並且每一個功能點之間耦合度太高。
用觀察者模式重構我們之前的程式碼:

  1. 編寫事件基類(主要2個方法:增加觀察者方法;事件通知方法)

    
    //事件產生者
    abstract  class EventGenerator{
        //儲存觀察者陣列(子類無需知道觀察者因此是private)
        private $observers = [];
    
        //增加觀察者
        function addObserver(Observer $observer){
            $this->observers[] = $observer;
        }
    
        //事件通知
        function notiy(){
            foreach ($this->observers as $item){
                $item->update();
            }
        }
    }
    
  2. 編寫觀察者介面
    
    interface Observer{
        //邏輯程式碼實現
        function update($evect_info = null);
    }
    
  3. 實現觀察者邏輯介面
    
    //邏輯1
    class Observer1 implements \Lib\Observer{
        function update($evect_info = null) {
            echo "給使用者發郵件";
        }
    }
    //邏輯2
    class Observer2 implements \Lib\Observer{
        function update($evect_info = null){
            echo "給商戶發郵件";
        }
    }
    
  4. 在主方法中呼叫
    
    class Order extends \Lib\EventGenerator {
        function trigger(){
            echo "下單成功";
            //呼叫該事件的通知觀察者方法
            $this->notiy();
        }
    }
    $event = new Event();
    //隨意增加(刪除)觀察者
    $event->addObserver(new \Lib\Observer1());
    $event->addObserver(new \Lib\Observer2());
    $event->trigger();
    

    總結:這樣就實現了各個邏輯程式碼之間的解耦。

相關文章