觀察者模式(Observer模式)

觀察者模式

在PHP SPL中已經(jīng)提供SplSubject和SqlOberver接口,源碼如下:

// 主題 被觀察者
interface SplSubject {
    public function attach(SplObserver $observer); //注冊(cè)觀察者到當(dāng)前主題
    public function detach(SplObserver $observer); //從當(dāng)前主題刪除觀察者
    public function notify(); //主題狀態(tài)更新時(shí)通知所有的觀察者做相應(yīng)的處理
}

// 觀察者
interface SplObserver {
    public function update(SplSubject $subject); //注冊(cè)觀察者到當(dāng)前主題
}

-------------------------------------具體實(shí)現(xiàn)-------------------------------------
<?php
/**
 * 主題類(lèi)(被觀察者相當(dāng)于一個(gè)主題,觀察者訂閱這個(gè)主題)
 * 當(dāng)我們注冊(cè)用戶(hù)成功的時(shí)候想發(fā)送 email 和 sms 通知用戶(hù)注冊(cè)成功
 * 則 可以將 SendEmail 和 SendSms 作為觀察者
 * 注冊(cè)到 User 的觀察者中
 * 當(dāng) User register 成功時(shí) notify 給 observers
 * 各 observe 通過(guò)約定的 update 接口進(jìn)行相應(yīng)的處理 發(fā)郵件或發(fā)短信
 */
class User implements SplSubject
{
    public $name;
    public $email;
    public $mobile;

    /**
     * 當(dāng)前主題下的觀察者集合
     * @var array
     */
    private $observers = [];

    /**
     * 模擬注冊(cè)
     * @param  [type] $name   [description]
     * @param  [type] $email  [description]
     * @param  [type] $mobile [description]
     * @return [type]         [description]
     */
    public function register($name, $email, $mobile)
    {
        $this->name   = $name;
        $this->email  = $email;
        $this->mobile = $mobile;

        //business handle and register success
        $reg_result = true;
        if ($reg_result) {
            $this->notify(); // 注冊(cè)成功 所有的觀察者將會(huì)收到此主題的通知
            return true;
        }

        return false;
    }

    /**
     * 當(dāng)前主題注冊(cè)新的觀察者
     * @param  SplObserver $observer [description]
     * @return [type]                [description]
     */
    public function attach(SplObserver $observer)
    {
        return array_push($this->observers, $observer);
    }

    /**
     * 當(dāng)前主題刪除已注冊(cè)的觀察者
     * @param  SplObserver $observer [description]
     * @return [type]                [description]
     */
    public function detach(SplObserver $observer)
    {
        $key = array_search($observer, $this->observers, true);

        if (false !== $key) {
            unset($this->observers[$key]);
            return true;
        }

        return false;
    }

    /**
     * 狀態(tài)更新 通知所有的觀察者
     * @return [type] [description]
     */
    public function notify()
    {
        if (! empty($this->observers)) {
            foreach ($this->observers as $key => $observer) {
                $observer->update($this);
            }
        }

        return true;
    }

}


-------------------------------------Email/Sms 觀察者-------------------------------------

/**
 * 觀察者通過(guò) update 來(lái)接受主題的更新通知
 */
class EmailObserver implements SplObserver
{
    /**
     * 觀察者接收主題通知的接口
     * @param  SplSubject $user [description]
     * @return [type]           [description]
     */
    public function update(SplSubject $user)
    {
        echo "send email to " . $user->email . PHP_EOL;
    }
}

class SmsObserver implements SplObserver
{
    public function update(SplSubject $user)
    {
        echo "send sms to " . $user->mobile . PHP_EOL;
    }
}
-------------------------------------業(yè)務(wù)-------------------------------------
// User 主題
$user = new User();

// 為 user 注冊(cè) Email 觀察者 (Email 觀察者訂閱 User 主題)
$emailObserver = new EmailObserver();
$user->attach($emailObserver);

// 為 user 注冊(cè) Sms 觀察者 (Sms 觀察者訂閱 User 主題)
$smsObserver = new SmsObserver();
$user->attach($smsObserver);

// 從 user 上刪除 Sms 觀察者 (Sms 觀察者取消訂閱 User 主題)
//$user->detach($smsObserver);

// register 中會(huì)根據(jù)注冊(cè)結(jié)果通知觀察者 觀察者做相應(yīng)的處理
$user->register("big cat", "32448732@qq.com", "1888888888");

-------------------------------------結(jié)果-------------------------------------

send email to 1226432372@qq.com
send sms to 1888888888
[Finished in 0.1s]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 寫(xiě)在前面 本文摘自:https://laravel-china.org/docs/php-design-patte...
    DragonRat閱讀 496評(píng)論 0 0
  • ** 創(chuàng)建型設(shè)計(jì)模式 **: 單例模式(Singleton Pattern) 工廠方法模式(Factor Patt...
    刀斧手何在閱讀 1,245評(píng)論 1 3
  • 設(shè)計(jì)模式是軟件開(kāi)發(fā)人員在軟件開(kāi)發(fā)過(guò)程中面臨的一般問(wèn)題的解決方案。這些解決方案是眾多軟件開(kāi)發(fā)人員經(jīng)過(guò)相當(dāng)長(zhǎng)的一段時(shí)間...
    garvin閱讀 232評(píng)論 0 1
  • 1.單例模式 單例模式顧名思義,就是只有一個(gè)實(shí)例。作為對(duì)象的創(chuàng)建模式, 單例模式確保某一個(gè)類(lèi)只有一個(gè)實(shí)例,而且自行...
    薛延祥閱讀 117評(píng)論 0 0
  • 易效能5.0第8周周總結(jié): 個(gè)人使命: 總綱:1.健康第一,睡眠充足,適當(dāng)運(yùn)動(dòng),綠色飲食;2.工作和生活平衡;3....
    張晨陽(yáng)_ccd9閱讀 235評(píng)論 0 0

友情鏈接更多精彩內(nèi)容