PHP中的觀察者模式介紹

觀察者模式

描述:

這個觀察者模式,大家可以去翻閱一下PHP手冊中的這兩個接口,下面我的代碼是根據這兩個接口來實現的

在公司上,我也有遇到過需要觀察者模式的,就好比如,衆多商品小表修改完之後,要統計在商品大表,這時候就可以考慮觀察者模式了

PHP中的接口如下:SplSubject,SPLObserver

第一個使用場景

當報紙發佈消息, 每一個用戶都會得到通知。這就是觀察者模式的使用場景。

第二個應用場景

下完訂單後,比如贈送什麼什麼東西

註冊完後,比如贈送什麼什麼東西

第三個使用場景

 場景描述:

 哈票以購票爲核心業務(此模式不限於該業務),但圍繞購票會產生不同的其他邏輯,如:

1、購票後記錄文本日誌

2、購票後記錄數據庫日誌

3、購票後發送短信

4、購票送抵扣卷、兌換卷、積分

5、其他各類活動等

傳統解決方案:在購票邏輯等類內部增加相關代碼,完成各種邏輯。

存在問題:

1、一旦某個業務邏輯發生改變,如購票業務中增加其他業務邏輯,需要修改購票核心文件、甚至購票流程。

2、日積月累後,文件冗長,導致後續維護困難。

存在問題原因主要是程序的"緊密耦合",使用觀察模式將目前的業務邏輯優化成"松耦合",達到易維護、易修改的目的,

同時也符合面向接口編程的思想。

 

<?php
// php 實現觀察者
// php5中提供觀察者observer與被觀察者subject的接口

// user ab 是被觀察
// SplSubject 實現這個接口就要實現三個方法
class user implements SplSubject
{
     public $lognum;
    public $hobby;
    protected $observers = null;

    public function __construct($hobby)
    {
        $this->lognum = rand(1, 10);
        $this->hobby = $hobby;
        $this->observers = new SplObjectStorage();
    }

    /***
     * 登錄
     */
    public function login()
    {
        // 操作session
        $this->notify();// 調用了,將觀察的東西都給我通知!
    }

    // 1 第一個方法 附加,附加一個SplObserver,以便可以將其通知更新。
    public function attach(SPLObserver $observer)
    {
        $this->observers->attach($observer);
    }

    // 2 第二個方法 分離,將觀察者從主題上移開,不再通知其更新。
    public function detach(SPLObserver $observer)
    {
        $this->observers->detach($observer);
    }

    // 3 第三個方法 通知,通知所有附加的觀察者。
    public function notify()
    {
        $this->observers->rewind();
        // rewind 裏面存儲了很多要通知的對象, 將迭代器後退到第一個存儲元素
        // valid 不斷判斷裏面的對象
        // current 獲取裏面的對象
        // update 接收主題更新
        // next 下一個
        while ($this->observers->valid()) {
            $observer = $this->observers->current();
            $observer->update($this);
            $this->observers->next();
        }
    }
}

// 登錄安全的
class secrity implements SPLObserver
{
    public function update(SplSubject $subject)
    {
        // TODO: Implement update() method.
        if ($subject->lognum < 3) {
            echo "這是第" . $subject->lognum . '次安全登錄';
        } else {
            echo "這是第" . $subject->lognum . '次安全,異常';
        }
    }
}

// 對應的人返回對應的需求
class ad implements SPLObserver
{
    public function update(SplSubject $subject)
    {
        // TODO: Implement update() method.
        if ($subject->hobby == 'sports') {
            echo '檯球英錦賽門票預訂';
        } else {
            echo '好好學習,天天向上';
        }
    }
}

// 實施觀察
$user = new user('study');
$user->attach(new secrity());// 觀察它
$user->attach(new ad()); // 觀察它
$user->login();

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章