亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

一步步理解觀察者模式

leanxi / 1123人閱讀

摘要:今天說說觀察者模式,這是一個非常常見的模式,很多事件的分發(fā)都基于此模式。這里將從一個題目來說說此模式的使用,有這樣一道題某市一家報社開張,市民訂閱報紙,嘗試使用觀察者模式解決此問題。在使用觀察者模式前,先說說普通的處理方法。

今天說說觀察者模式,這是一個非常常見的模式,很多事件的分發(fā)都基于此模式。

這里將從一個題目來說說此模式的使用,有這樣一道題:

某市一家報社開張,市民訂閱報紙,嘗試使用觀察者模式解決此問題。

在使用觀察者模式前,先說說普通的處理方法。

class Publisher {
    public $title = "";

    public function __construct($title) {
        $this->title = $title;
    }

    public function push() {
        echo "【{$this->title}】發(fā)布新聞" . PHP_EOL;
    }
}

class People {
    public $name = "";

    public function __construct($name) {
        $this->name = $name;
    }

    public function pull(Publisher $publisher) {
        echo "【{$this->name}】接收到【{$publisher->title}】發(fā)布的新聞" . PHP_EOL;
    }
}

/* 初始化用戶 */
$peoples = [];
for ($i = 1; $i <= 5; $i++) {
    $peoples[] = new People("用戶{$i}");
}

/* 報社使用 push 方法發(fā)布新聞 */
$publisher = new Publisher("報社1");
$publisher->push();

/* 所有訂閱的市民使用 pull 方法接收報社對象 */
foreach ($peoples as $people) {
    $people->pull($publisher);
}

每次 publishier 使用 push 方法,都需要循環(huán)一遍 $peoples 進(jìn)行通知,當(dāng)然這里可以通過一個函數(shù)封裝起來,每次調(diào)用即可。

以下是運行截圖:

以上代碼運行肯定是沒有任何問題的,也特別容易理解。只要運行了 push 方法,就循環(huán)調(diào)用一遍 pull 方法。但每次調(diào)用特別麻煩,有么有更好的改進(jìn)呢?

來看一下接下來的代碼:

class Publisher {
    public $title = "";
    private $peoples = [];

    public function __construct($title, $peoples) {
        $this->title = $title;
        $this->peoples = $peoples;
    }

    public function push() {
        echo "【{$this->title}】發(fā)布新聞" . PHP_EOL;

        // 一旦發(fā)布新聞,就通知所有訂閱用戶
        foreach ($this->peoples as $people) {
            // 這里注意有 $this
            $people->pull($this);
        }
    }
}

// 原先的 People 類不變,此處省略

$peoples = [];
for ($i = 1; $i <= 5; $i++) {
    $peoples[] = new People("用戶{$i}");
}

// 創(chuàng)建 $publisher 時,直接將 $peoples 傳給報社
$publisher = new Publisher("報社1", $peoples);
$publisher->push();

這里可以看到已經(jīng)將循環(huán)移入了 Publisher 類中,每次只要執(zhí)行 push 方法,所有的 people 對象都能收到消息。

可是這里 $peoples 是通過構(gòu)造函數(shù)傳進(jìn)去的,能不能進(jìn)行分離呢?

下面就改寫一下代碼:

class Publisher {
    public $title = "";
    private $peoples = [];

    public function __construct($title) {
        $this->title = $title;
    }

    public function addPeople(People $people) {
        $this->peoples[] = $people;
    }

    public function push() {
        echo "【{$this->title}】發(fā)布新聞" . PHP_EOL;

        foreach ($this->peoples as $people) {
            $people->pull($this);
        }
    }
}

// 客戶端
$publisher = new Publisher("報社1");

for ($i = 1; $i <= 5; $i++) {
    $publisher->addPeople(new People("用戶{$i}"));
}

$publisher->push();

改成這樣后使用非常方便,思路也非常清晰。

以上就是觀察者模式的雛形,接下來就是抽象化了...

interface IObserver {
    public function update(Publisher $publisher);
}

class Publisher {
    public $title = "";
    private $observers = [];

    public function __construct($title) {
        $this->title = $title;
    }

    public function attach(IObserver $observer) {
        $this->observers[] = $observer;
    }

    public function push() {
        echo "【{$this->title}】發(fā)布新聞" . PHP_EOL;

        foreach ($this->observers as $observer) {
            $observer->update($this);
        }
    }
}

class People implements IObserver {
    public $name = "";

    public function __construct($name) {
        $this->name = $name;
    }

    public function update(Publisher $publisher) {
        echo "【{$this->name}】接收到【{$publisher->title}】發(fā)布的新聞" . PHP_EOL;
    }
}

$publisher = new Publisher("報社1");

for ($i = 1; $i <= 5; $i++) {
    $publisher->attach(new People("用戶{$i}"));
}

$publisher->push();

以上就是比較標(biāo)準(zhǔn)的觀察者模式結(jié)構(gòu),其中需要說明的是在 IObserver 接口中定義的 update 方法參數(shù)是可以根據(jù)場景需要進(jìn)行修改的。

另一個需要說的是在 Publisher 類中,可以創(chuàng)建一個 detach 方法用于退訂。這樣整個對于 $peoples 的管理就相對完整一些了。

其實有時候覺得學(xué)習(xí)設(shè)計模式不要學(xué)的太死了,只要思路對,怎么寫都可以。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/31403.html

相關(guān)文章

  • 使用合適的設(shè)計模式步步優(yōu)化前端代碼

    摘要:修改配置遠(yuǎn)比修改源代碼要簡單的多。在年提出了種設(shè)計模式。常用的設(shè)計模式及設(shè)計原則可以參考下面的思維導(dǎo)圖。每種設(shè)計模式都有它的適應(yīng)場景,有的場景也會使用多種設(shè)計模式。包含文章視頻源代碼原創(chuàng)新書移動前端高效開發(fā)實戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開售。 作者:曉飛本文原創(chuàng),轉(zhuǎn)載請注明作者及出處 在后端語言中,設(shè)計模式應(yīng)用的較為廣泛。如Spring中常見的工廠模式、裝飾者模式、單例模式、迭代器模式。但是...

    alin 評論0 收藏0
  • 步步做組件-學(xué)校選擇器(系列)

    摘要:文章一步步做組件學(xué)校選擇器版本添加自定義事件,即使用觀察者模式。文章一步步做組件學(xué)校選擇器版本后增實現(xiàn)學(xué)校選擇器的模態(tài)對話框,并在頁面中共用同一個選擇器對象。監(jiān)聽時判斷,回調(diào)時判斷,文章一步步做組件學(xué)校選擇器 前言 年初的時候?qū)戇^一個js組件的系列文章,博客原文地址為 http://jsorz.cn/blog/2015/02/step-by-step-js-component-scho...

    galois 評論0 收藏0
  • 從源碼看 Promise 概念與實現(xiàn)

    摘要:從源碼看概念與實現(xiàn)是異步編程中的重要概念,它較好地解決了異步任務(wù)中回調(diào)嵌套的問題。這些概念中有趣的地方在于,標(biāo)識狀態(tài)的變量如都是形容詞,用于傳入數(shù)據(jù)的接口如與都是動詞,而用于傳入回調(diào)函數(shù)的接口如及則在語義上用于修飾動詞的副詞。 從源碼看 Promise 概念與實現(xiàn) Promise 是 JS 異步編程中的重要概念,它較好地解決了異步任務(wù)中回調(diào)嵌套的問題。在沒有引入新的語言機制的前提下,這...

    kel 評論0 收藏0
  • javascript設(shè)計模式察者模式

    摘要:下面為學(xué)習(xí)筆記,對觀察者模式做簡單實現(xiàn)。注冊的事件被觸發(fā)后需要執(zhí)行的動作注冊事件及對應(yīng)的執(zhí)行動作觸發(fā)事件對比執(zhí)行事件前后的事件列表內(nèi)容觀察者模式在解決類的耦合中的應(yīng)用小例子。 這篇筆記主要記錄學(xué)習(xí)思路及收獲,分享出來拋磚引玉,如有謬誤或優(yōu)化空間,歡迎交流。 要理解觀察者模式,可以類比vue中的EventBus,其實就是一個全局的觀察者對象($bus),上面有注冊事件($bus.on()...

    Tamic 評論0 收藏0
  • JAVA NIO 步步構(gòu)建I/O多路復(fù)用的請求模型

    摘要:為解決這問題,我們發(fā)現(xiàn)元兇處在一線程一請求上,如果一個線程能同時處理多個請求,那么在高并發(fā)下性能上會大大改善。這樣一個線程可以同時發(fā)起多個調(diào)用,并且不需要同步等待數(shù)據(jù)就緒。表示當(dāng)前就緒的事件類型。 JAVA NIO 一步步構(gòu)建I/O多路復(fù)用的請求模型 摘要:本文屬于原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請保留出處:https://github.com/jasonGeng88/blog 文章一:JAVA ...

    X_AirDu 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<