成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Laravel核心解讀--觀察者模式

lei___ / 1934人閱讀

摘要:模式定義觀察者模式定義對(duì)象間的一種一對(duì)多依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí),其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新。

觀察者模式

Laravel的Event事件系統(tǒng)提供了一個(gè)簡(jiǎn)單的觀察者模式實(shí)現(xiàn),能夠訂閱和監(jiān)聽?wèi)?yīng)用中發(fā)生的各種事件,在PHP的標(biāo)準(zhǔn)庫(kù)(SPL)里甚至提供了三個(gè)接口SplSubject, SplObserver, SplObjectStorage來(lái)讓開發(fā)者更容易地實(shí)現(xiàn)觀察者模式,不過(guò)我還是想脫離SPL提供的接口和特定編程語(yǔ)言來(lái)說(shuō)一下如何通過(guò)面向?qū)ο蟪绦蛟O(shè)計(jì)來(lái)實(shí)現(xiàn)觀察者模式,示例是PHP代碼不過(guò)用其他面向?qū)ο笳Z(yǔ)言實(shí)現(xiàn)起來(lái)也是一樣的。

模式定義

觀察者模式(Observer Pattern):定義對(duì)象間的一種一對(duì)多依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí),其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新。觀察者模式又叫做發(fā)布-訂閱(Publish/Subscribe)模式、模型-視圖(Model/View)模式、源-監(jiān)聽器(Source/Listener)模式或從屬者(Dependents)模式。

觀察者模式的核心在于Subject和Observer接口,Subject(主題目標(biāo))包含一個(gè)給定的狀態(tài),觀察者“訂閱”這個(gè)主題,將主題的當(dāng)前狀態(tài)通知觀察者,每次給定狀態(tài)改變時(shí)所有觀察者都會(huì)得到通知。

發(fā)生改變的對(duì)象稱為觀察目標(biāo),而被通知的對(duì)象稱為觀察者,一個(gè)觀察目標(biāo)可以對(duì)應(yīng)多個(gè)觀察者,而且這些觀察者之間沒(méi)有相互聯(lián)系,可以根據(jù)需要增加和刪除觀察者,使得系統(tǒng)更易于擴(kuò)展。

模式結(jié)構(gòu)說(shuō)明

Subject 目標(biāo)抽象類

ConcreteSubject 具體目標(biāo)

Observer 觀察者抽象類

ConcreteObserver 具體觀察者

應(yīng)用舉例

比如在設(shè)置用戶(主題)的狀態(tài)后要分別發(fā)送當(dāng)前的狀態(tài)描述信息給用戶的郵箱和手機(jī),我們可以使用兩個(gè)觀察者訂閱用戶的狀態(tài),一旦設(shè)置狀態(tài)后主題就會(huì)通知的訂閱了狀態(tài)改變的觀察者,在兩個(gè)觀察者里面我們可以分別來(lái)實(shí)現(xiàn)發(fā)送郵件信息和短信信息的功能。

抽象目標(biāo)類

abstract class Subject
{
    protected $stateNow;
    protected $observers = [];

    public function attach(Observer $observer)
    {
        array_push($this->observers, $observer);
    }

    public function detach(Observer $ob)
    {
        $pos = 0;
        foreach ($this->observers as $viewer) {
            if ($viewer == $ob) {
                array_splice($this->observers, $pos, 1);
            }
            $pos++;
        }
    }

    public function notify()
    {
        foreach ($this->observers as $viewer) {
            $viewer->update($this);
        }
    }
}

在抽象類中attach detachnotify都是具體方法,這些是繼承才能使用的方法,將由Subject的子類使用。

具體目標(biāo)類

class ConcreteSubject extends Subject
{
    public function setState($state) 
    {
        $this->stateNow = $state;
        $this->notify();
    }

    public function getState()
    {
        return $this->stateNow;
    }
}

抽象觀察者

abstract class Observer
{
    abstract public function update(Subject $subject);
}

在抽象觀察者中,抽象方法update等待子類為它提供一個(gè)特定的實(shí)現(xiàn)。

具體觀察者

class ConcreteObserverDT extends Observer
{
    private $currentState;

    public function update(Subject $subject)
    {
        $this->currentState = $subject->getState();

        echo "
". $this->currentState ."
"; } } class ConcreteObserverPhone extends Observer { private $currentState; public function update(Subject $subject) { $this->currentState = $subject->getState(); echo "
". $this->currentState ."
"; } }

在例子中為了理解起來(lái)簡(jiǎn)單,我們只是根據(jù)不同的客戶端設(shè)置了不同的內(nèi)容樣式,實(shí)際應(yīng)用中可以真正的調(diào)用郵件和短信服務(wù)來(lái)發(fā)送信息。

使用觀察者模式

class Client 
{
    public function __construct()
    {
        $sub = new ConcreteSubject();

        $obDT = new ConcreteObserverDT();
        $obPhone = new ConcreteObserverPhone();

        $sub->attach($obDT);
        $sub->attach($obPhone);
        $sub->setState("Hello World");
    }
}

$worker = new Client();
何時(shí)使用觀察者模式

一個(gè)對(duì)象的改變將導(dǎo)致其他一個(gè)或多個(gè)對(duì)象也發(fā)生改變,而不知道具體有多少對(duì)象將發(fā)生改變,可以降低對(duì)象之間的耦合度。

一個(gè)對(duì)象必須通知其他對(duì)象,而并不知道這些對(duì)象是誰(shuí)。

基于事件觸發(fā)機(jī)制來(lái)解耦復(fù)雜邏輯時(shí),從整個(gè)邏輯的不同關(guān)鍵點(diǎn)抽象出不同的事件,主流程只需要關(guān)心最核心的邏輯并能正確地觸發(fā)事件(Subject),其余相關(guān)功能實(shí)現(xiàn)由觀察者或者叫訂閱者來(lái)完成。

總結(jié)

觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同時(shí)監(jiān)聽某一個(gè)目標(biāo)對(duì)象,當(dāng)這個(gè)目標(biāo)對(duì)象的狀態(tài)發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,使它們能夠自動(dòng)更新。

模式包含四個(gè)角色:目標(biāo)又稱為主題,它是指被觀察的對(duì)象;具體目標(biāo)是目標(biāo)類的子類,通常它包含有經(jīng)常發(fā)生改變的數(shù)據(jù),當(dāng)它的狀態(tài)發(fā)生改變時(shí),向它的各個(gè)觀察者發(fā)出通知;觀察者將對(duì)觀察目標(biāo)的改變做出反應(yīng);在具體觀察者中維護(hù)一個(gè)指向具體目標(biāo)對(duì)象的引用,它存儲(chǔ)具體觀察者的有關(guān)狀態(tài),這些狀態(tài)需要和具體目標(biāo)的狀態(tài)保持一致。

觀察者模式的主要優(yōu)點(diǎn)在于可以實(shí)現(xiàn)表示層和數(shù)據(jù)邏輯層的分離,并在觀察目標(biāo)和觀察者之間建立一個(gè)抽象的耦合,支持廣播通信;其主要缺點(diǎn)在于如果一個(gè)觀察目標(biāo)對(duì)象有很多直接和間接的觀察者的話,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間,而且如果在觀察者和觀察目標(biāo)之間有循環(huán)依賴的話,觀察目標(biāo)會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用,可能導(dǎo)致系統(tǒng)崩潰。

本文已經(jīng)收錄在系列文章Laravel源碼學(xué)習(xí)里,歡迎訪問(wèn)閱讀。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/28804.html

相關(guān)文章

  • Laravel核心解讀 -- 事件系統(tǒng)

    摘要:對(duì)于包含通配符的事件名,會(huì)被統(tǒng)一放入數(shù)組中,是用來(lái)創(chuàng)建事件對(duì)應(yīng)的的如果是監(jiān)聽器是類,去創(chuàng)建監(jiān)聽類創(chuàng)建的時(shí)候,會(huì)判斷監(jiān)聽對(duì)象是監(jiān)聽類還是閉包函數(shù)。對(duì)于閉包監(jiān)聽來(lái)說(shuō),會(huì)再包裝一層返回一個(gè)閉包函數(shù)作為事件的監(jiān)聽者。 事件系統(tǒng) Laravel 的事件提供了一個(gè)簡(jiǎn)單的觀察者實(shí)現(xiàn),能夠訂閱和監(jiān)聽?wèi)?yīng)用中發(fā)生的各種事件。事件機(jī)制是一種很好的應(yīng)用解耦方式,因?yàn)橐粋€(gè)事件可以擁有多個(gè)互不依賴的監(jiān)聽器。lar...

    chengjianhua 評(píng)論0 收藏0
  • Laravel核心解讀 -- 外觀模式

    摘要:外觀模式的目的在于降低系統(tǒng)的復(fù)雜程度。在不引入抽象外觀類的情況下,增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼,違背了開閉原則。 外觀模式 外觀模式(Facade Pattern):外部與一個(gè)子系統(tǒng)的通信必須通過(guò)一個(gè)統(tǒng)一的外觀對(duì)象進(jìn)行,為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,外觀模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。外觀模式又稱為門面模式,它是一種對(duì)象結(jié)構(gòu)型模...

    zoomdong 評(píng)論0 收藏0
  • Laravel核心解讀--中間件(Middleware)

    摘要:解析出后將進(jìn)入應(yīng)用的請(qǐng)求對(duì)象傳遞給的方法,在方法負(fù)責(zé)處理流入應(yīng)用的請(qǐng)求對(duì)象并返回響應(yīng)對(duì)象。攜帶了本次迭代的值。通過(guò)這種方式讓請(qǐng)求對(duì)象依次流過(guò)了要通過(guò)的中間件,達(dá)到目的地的方法。 中間件(Middleware)在Laravel中起著過(guò)濾進(jìn)入應(yīng)用的HTTP請(qǐng)求對(duì)象(Request)和完善離開應(yīng)用的HTTP響應(yīng)對(duì)象(Reponse)的作用, 而且可以通過(guò)應(yīng)用多個(gè)中間件來(lái)層層過(guò)濾請(qǐng)求、逐步完善...

    enda 評(píng)論0 收藏0
  • Laravel核心解讀 -- 用戶認(rèn)證系統(tǒng)(基礎(chǔ)介紹)

    摘要:系統(tǒng)的核心是由的認(rèn)證組件的看守器和提供器組成。使用的認(rèn)證系統(tǒng),幾乎所有東西都已經(jīng)為你配置好了。其配置文件位于,其中包含了用于調(diào)整認(rèn)證服務(wù)行為的注釋清晰的選項(xiàng)配置。 用戶認(rèn)證系統(tǒng)(基礎(chǔ)介紹) 使用過(guò)Laravel的開發(fā)者都知道,Laravel自帶了一個(gè)認(rèn)證系統(tǒng)來(lái)提供基本的用戶注冊(cè)、登錄、認(rèn)證、找回密碼,如果Auth系統(tǒng)里提供的基礎(chǔ)功能不滿足需求還可以很方便的在這些基礎(chǔ)功能上進(jìn)行擴(kuò)展。這篇...

    RebeccaZhong 評(píng)論0 收藏0
  • Laravel核心解讀--完結(jié)篇

    摘要:過(guò)去一年時(shí)間寫了多篇文章來(lái)探討了我認(rèn)為的框架最核心部分的設(shè)計(jì)思路代碼實(shí)現(xiàn)。為了大家閱讀方便,我把這些源碼學(xué)習(xí)的文章匯總到這里。數(shù)據(jù)庫(kù)算法和數(shù)據(jù)結(jié)構(gòu)這些都是編程的內(nèi)功,只有內(nèi)功深厚了才能解決遇到的復(fù)雜問(wèn)題。 過(guò)去一年時(shí)間寫了20多篇文章來(lái)探討了我認(rèn)為的Larave框架最核心部分的設(shè)計(jì)思路、代碼實(shí)現(xiàn)。通過(guò)更新文章自己在軟件設(shè)計(jì)、文字表達(dá)方面都有所提高,在剛開始決定寫Laravel源碼分析地...

    laoLiueizo 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<