国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

設(shè)計(jì)模式 -- 觀察者模式

chengtao1633 / 881人閱讀

摘要:總結(jié)一下從表面上看觀察者模式里,只有兩個(gè)角色觀察者被觀察者而發(fā)布訂閱模式,卻不僅僅只有發(fā)布者和訂閱者兩個(gè)角色,還有第三個(gè)角色經(jīng)紀(jì)人存在。參考鏈接觀察者模式發(fā)布訂閱模式

做了這么長(zhǎng)時(shí)間的 菜鳥程序員 ,我好像還沒(méi)有寫過(guò)一篇關(guān)于設(shè)計(jì)模式的博客...咳咳...意外,純屬意外。所以,我決定,從這一刻起,我要把設(shè)計(jì)模式在從頭學(xué)習(xí)一遍,不然都對(duì)不起我這 菜鳥 的身份。那這次,就從觀察者模式開始好啦...至于其他的,慢慢來(lái)。廢話不多說(shuō),還是進(jìn)入正題吧!

從定義上看:觀察者模式 是當(dāng)對(duì)象(不知道什么是對(duì)象的,面壁思過(guò)切...)間存在一對(duì)多關(guān)系時(shí),則使用 觀察者模式 ,比如,當(dāng)一個(gè)對(duì)象被修改時(shí),則會(huì)自動(dòng)通知它的依賴對(duì)象。觀察者模式 屬于 行為型模式 (不會(huì)還要讓我講一下設(shè)計(jì)模式的分類吧?我不要在這里講...)。

其實(shí),我所理解的 觀察者模式 ,就是觀察和被觀察對(duì)象之間的關(guān)系,好比說(shuō),在拍賣的時(shí)候,拍賣師觀察最高標(biāo)價(jià),然后通知給其他競(jìng)價(jià)者競(jìng)價(jià)。在這里面,拍賣師是觀察者,而那些競(jìng)價(jià)者,是被觀察者,文字不太好理解是吧,那我們畫個(gè)圖看一下:

從圖中我們可以看到,拍賣師觀察競(jìng)價(jià)者1的標(biāo)價(jià),拿到了最高標(biāo)價(jià),然后在通知其他競(jìng)價(jià)者,這就是一個(gè)簡(jiǎn)單的觀察者模式圖示,仔細(xì)看一下這個(gè)圖,我們會(huì)發(fā)現(xiàn),最基礎(chǔ)的觀察者模式中,涉及以下幾種角色:

被觀察者:競(jìng)價(jià)者們;

觀察者:拍賣師;

具體的被觀察者:競(jìng)價(jià)者們的出價(jià)動(dòng)作;

具體的觀察者:拍賣師觀察競(jìng)價(jià)者的動(dòng)作;

按照上述的四種角色,我們來(lái)用代碼還原一下觀察者模式的實(shí)現(xiàn):

/**
 * 抽象被觀察者(競(jìng)價(jià)者們)
 **/
public abstract class Subject {
    // 用來(lái)保存注冊(cè)的觀察者對(duì)象
    private List list = new ArrayList<>();

    // 注冊(cè)觀察者對(duì)象
    public void attach(Observer observer) {
        list.add(observer);
        System.out.println("Attached an observer");
    }

    // 通知所有注冊(cè)的觀察者對(duì)象
    public void nodifyObservers(int price) {
        for (Observer observer : list) {
            observer.update(price);
        }
    }
}

/**
 * 抽象觀察者角色類(拍賣師)
 **/
public interface Observer {
    public void update(int price);
}

/**
 * 具體的被觀察者實(shí)現(xiàn)類(競(jìng)價(jià)者們的動(dòng)作)
 **/
public class BidderSubject extends Subject {
    private int price;
    
    public void change(int price) {
        this.price = price;
        System.out.println("競(jìng)價(jià)者說(shuō):" + price + "元");
        // 競(jìng)價(jià)者們說(shuō)出價(jià)格,通知觀察者
        this.nodifyObservers(price);
    }
}

/**
 * 具體的觀察者實(shí)現(xiàn)類(拍賣師的動(dòng)作)
 **/
public class AuctionObserver implements Observer {
    // 觀察者的動(dòng)作
    private int observerAction;

    @Override
    public void update(int price) {
        // 更新觀察者的動(dòng)作,使其與被觀察者(競(jìng)價(jià)者們出價(jià))的消息保持一致
        observerAction = price;
        System.out.println("好,某某出價(jià)為:" + observerAction + "元,還有沒(méi)有更高的?");
    }
}

/**
 * 客戶端執(zhí)行類
 **/
public class Main {
    public static void main(String[] args) {
        // 創(chuàng)建被觀察者(競(jìng)價(jià)者)主題對(duì)象
        BidderSubject bidderSubject = new BidderSubject();
        // 創(chuàng)建觀察者(拍賣師)對(duì)象
        Observer observer = new AuctionObserver();
        // 將觀察者(拍賣師)對(duì)象登記到被觀察對(duì)象(競(jìng)價(jià)者們)上
        bidderSubject.attach(observer);
        // 改變被觀察者(競(jìng)價(jià)者們)的出價(jià)
        bidderSubject.change(20);
    }
}

最后我們看一下執(zhí)行結(jié)果:

其實(shí)在 Java 中,還是比較容易理解抽象這個(gè)概念,但是在 JavaScript 語(yǔ)言中,因?yàn)闆](méi)有 多態(tài) ,所以在實(shí)現(xiàn)上,沒(méi)有 java 這么明顯的看出觀察者和被觀察者的關(guān)系,但是我們還是可以實(shí)現(xiàn)這個(gè)觀察者模式,在這里,博主使用的是 es6 的一個(gè)新特性:ProxyReflect ,這兩個(gè) api 的具體使用這里就不在贅述了,有興趣的可以看看 阮一峰 老師的 ES6入門學(xué)習(xí) ,具體的還是讓我們直接看代碼吧:

// 添加觀察者的方法
const observers = new Set();
const observe = fn => observers.add(fn);

// 設(shè)置Proxy的set方法
function set(target, key, value, receiver) {
  console.log(`競(jìng)價(jià)者說(shuō):${value}元`);
  const result = Reflect.set(target, key, value, receiver);
  observers.forEach(observer => observer());
  return result;
}

// 創(chuàng)建Proxy代理,實(shí)現(xiàn)被觀察者對(duì)象的抽象
const subject = obj => new Proxy(obj, {set});

// 被觀察者(競(jìng)價(jià)者們)對(duì)象,默認(rèn)數(shù)值
const bidderSubject = subject({
  price: 0,
});

// 觀察者(拍賣師)對(duì)象
function auctionObserver() {
  console.log(`拍賣師說(shuō):有人出價(jià)${bidderSubject.price}元,還有沒(méi)有要出價(jià)的?`);
}

// 添加觀察者
observe(auctionObserver);
// 競(jìng)價(jià)者出價(jià)
bidderSubject.price = 20;

執(zhí)行結(jié)果與上面 Java 是一致的,還是上圖吧,證明一下博主是木有說(shuō)謊的:

這就是簡(jiǎn)單的觀察者實(shí)現(xiàn)方式,在 javascript 我們有輔助的 api 就是 ProxyReflect,翻譯成中文是 代理反射,別小看這他倆哈,作用其實(shí)很大的,具體的就不在這里說(shuō)了,以后有機(jī)會(huì)給大家補(bǔ)一篇具體的使用說(shuō)明。

其實(shí)我們?cè)趯W(xué)習(xí) 觀察者模式 的時(shí)候,還會(huì)蹦出來(lái)一個(gè)詞語(yǔ)叫 發(fā)布-訂閱模式,大多數(shù)人都會(huì)說(shuō),這倆可以劃等號(hào),但是他們真的可以劃等號(hào)么?答案就是(PS:博主的表情是壞笑):不,他們不是一個(gè)東西,(戲精出現(xiàn):what?why?)。

網(wǎng)上有個(gè)說(shuō)法是:觀察者模式 是為了實(shí)現(xiàn)松耦合,我們從 Java 的代碼看到,實(shí)現(xiàn) 觀察者模式 用的是面向接口編程,整套實(shí)現(xiàn)的流程是:change() 方法所在的實(shí)例對(duì)象,就是 被觀察者 (Subject類)只需要維護(hù)一套 觀察者(Observer) 的集合,這些 Observer 實(shí)現(xiàn)相同的接口,Subject只需要知道,通知 Observer 時(shí),需要調(diào)用哪個(gè)統(tǒng)一方法(例子中的 change()方法)就好了。

發(fā)布-訂閱模式 呢,發(fā)布者(被觀察者),并不會(huì)直接通知訂閱者(觀察者),換句話說(shuō),發(fā)布者和訂閱者,彼此互不相識(shí),或許這里該有同學(xué)問(wèn)了:他們互不相識(shí)?那他們之間該如何交流呢?答案是:通過(guò)第三者,也就是在消息隊(duì)列里面,我們常說(shuō)的 經(jīng)紀(jì)人-Broker
> 發(fā)布者只需要告訴 Broker,我要發(fā)的消息是,price是20,
> 訂閱者只需要告訴 Broker,我要訂閱price是20的消息。

于是,當(dāng) Broker 收到 發(fā)布者 發(fā)過(guò)來(lái)消息,并且price是20時(shí),就會(huì)把消息推送給訂閱了price是20的 訂閱者。當(dāng)然也有可能是 訂閱者 自己過(guò)來(lái)拉取,看具體實(shí)現(xiàn)。

也就是說(shuō),發(fā)布-訂閱模式里發(fā)布者訂閱者,不是松耦合,而是完全解耦的

總結(jié)一下:

從表面上看:

觀察者模式里,只有兩個(gè)角色 —— 觀察者+被觀察者

而發(fā)布訂閱模式,卻不僅僅只有發(fā)布者和訂閱者兩個(gè)角色,還有第三個(gè)角色-經(jīng)紀(jì)人Broker存在。

往更深層次講:

觀察者和被觀察者,是松耦合的關(guān)系;

發(fā)布者和訂閱者,則完全不存在耦合。

其實(shí)我們?cè)趯W(xué)習(xí)設(shè)計(jì)模式的時(shí)候,很多模式的實(shí)現(xiàn),都是有一定依據(jù)的,首先離不開的就是面向?qū)ο笕筇匦裕浯问敲嫦驅(qū)ο笃叽笤瓌t,而設(shè)計(jì)模式則是對(duì)面向?qū)ο蟾唧w的實(shí)現(xiàn),我們學(xué)習(xí)這些模式的時(shí)候,還是要多去寫代碼實(shí)踐一下,這些能有效的幫助我們優(yōu)化代碼。

參考鏈接:
觀察者模式 vs 發(fā)布訂閱模式

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104982.html

相關(guān)文章

  • 設(shè)計(jì)模式察者設(shè)計(jì)模式

    摘要:關(guān)鍵概念理解觀察者設(shè)計(jì)模式中主要區(qū)分兩個(gè)概念觀察者指觀察者對(duì)象,也就是消息的訂閱者被觀察者指要觀察的目標(biāo)對(duì)象,也就是消息的發(fā)布者。 原文首發(fā)于微信公眾號(hào):jzman-blog,歡迎關(guān)注交流! 最近補(bǔ)一下設(shè)計(jì)模式相關(guān)的知識(shí),關(guān)于觀察者設(shè)計(jì)模式主要從以下幾個(gè)方面來(lái)學(xué)習(xí),具體如下: 什么是觀察者設(shè)計(jì)模式 關(guān)鍵概念理解 通知觀察者的方式 觀察者模式的實(shí)現(xiàn) 觀察者模式的優(yōu)缺點(diǎn) 使用場(chǎng)景 下面...

    NotFound 評(píng)論0 收藏0
  • 設(shè)計(jì)模式察者模式與發(fā)布訂閱模式

    摘要:觀察者模式與發(fā)布訂閱的區(qū)別在模式中,知道,同時(shí)還保留了的記錄。發(fā)布者訂閱者在大多情況下是異步方式使用消息隊(duì)列。圖片源于網(wǎng)絡(luò)侵權(quán)必刪如果以結(jié)構(gòu)來(lái)分辨模式,發(fā)布訂閱模式相比觀察者模式多了一個(gè)中間件訂閱器,所以發(fā)布訂閱模式是不同于觀察者模式的。 學(xué)習(xí)了一段時(shí)間設(shè)計(jì)模式,當(dāng)學(xué)到觀察者模式和發(fā)布訂閱模式的時(shí)候遇到了很大的問(wèn)題,這兩個(gè)模式有點(diǎn)類似,有點(diǎn)傻傻分不清楚,博客起因如此,開始對(duì)觀察者和發(fā)布...

    BaronZhang 評(píng)論0 收藏0
  • 設(shè)計(jì)模式 -- 察者模式

    摘要:總結(jié)一下從表面上看觀察者模式里,只有兩個(gè)角色觀察者被觀察者而發(fā)布訂閱模式,卻不僅僅只有發(fā)布者和訂閱者兩個(gè)角色,還有第三個(gè)角色經(jīng)紀(jì)人存在。參考鏈接觀察者模式發(fā)布訂閱模式 做了這么長(zhǎng)時(shí)間的 菜鳥程序員 ,我好像還沒(méi)有寫過(guò)一篇關(guān)于設(shè)計(jì)模式的博客...咳咳...意外,純屬意外。所以,我決定,從這一刻起,我要把設(shè)計(jì)模式在從頭學(xué)習(xí)一遍,不然都對(duì)不起我這 菜鳥 的身份。那這次,就從觀察者模式開始好啦...

    makeFoxPlay 評(píng)論0 收藏0
  • 訂閱發(fā)布模式察者模式的區(qū)別

    摘要:或許以前認(rèn)為訂閱發(fā)布模式是觀察者模式的一種別稱,但是發(fā)展至今,概念已經(jīng)有了不少區(qū)別。參考文章訂閱發(fā)布模式和觀察者模式真的不一樣 首選我們需要先了解兩者的定義和實(shí)現(xiàn)的方式,才能更好的區(qū)分兩者的不同點(diǎn)。 或許以前認(rèn)為訂閱發(fā)布模式是觀察者模式的一種別稱,但是發(fā)展至今,概念已經(jīng)有了不少區(qū)別。 訂閱發(fā)布模式 在軟件架構(gòu)中,發(fā)布-訂閱是一種消息范式,消息的發(fā)送者(稱為發(fā)布者)不會(huì)將消息直接發(fā)送給特...

    ysl_unh 評(píng)論0 收藏0
  • 設(shè)計(jì)模式-察者模式

    摘要:觀察者模式又稱發(fā)布訂閱模式,模型視圖模式,源監(jiān)聽器模式模式或者從屬者模式。第一方法被調(diào)用之后會(huì)設(shè)置一個(gè)內(nèi)部標(biāo)記變量,代表被觀察者對(duì)象的狀態(tài)發(fā)生了變化。代碼地址觀察者模式代碼自己實(shí)現(xiàn)的觀察者模式利用提供的有關(guān)觀察者模式的 概念 定義了對(duì)象之間的一對(duì)多依賴,當(dāng)一個(gè)對(duì)象狀態(tài)改變時(shí),它的所有依賴者都會(huì)收到通知并自動(dòng)更新。觀察者模式又稱發(fā)布(Publish/Subscribe)訂閱模式,模型視圖...

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

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

0條評(píng)論

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