<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                >[success] # 觀察者(發布訂閱模式)菜鳥教程的總結 ~~~ 1.定義:當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。 比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。 2.主要解決:一個對象狀態改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協作。 3.何時使用:一個對象(目標對象)的狀態發生改變,所有的依賴對象(觀察者對象)都將得到通知,進行廣播通知。 4.如何解決:使用面向對象技術,可以將這種依賴關系弱化(針對java來說) 5.關鍵代碼:在抽象類里有一個 ArrayList 存放觀察者們。 (針對前端也適用就是說我們需要緩存這些要被通知的對象通過某種儲存變量) ~~~ * 說明 ~~~ 1.有些文章是將觀察者模式 和 發布訂閱模式相區分,如果從定義上來說來著都是對象存在一對多的關系,當一個 被改變的時候通知其他依賴對象,所以二者在這個角度上來說我認為是相同的,但是從代碼結構角度來說,二者 不同點就是'觀察者模式'比'發布訂閱模式'少了個中轉 2.這里有點繞的地方 2.1.'觀察者模式'角度來說,一對多的關系中的多指的是'觀察者',這個一指的是用來收集這些觀察 者的對象,當收集這些觀察者的這個唯一對象發生了改變,那么這些多個'觀察者'會隨之變化 2.2.'發布訂閱模式'角度來說,一對多的關系中多指的是'訂閱者',一指的是發布者,也就說發布者出現了 變化所有的訂閱者都會產生相應的變化 2.3'觀察者'這個詞的理解就是,負責觀察外界影響條件,來告訴被觀察者需要接受或者改變。 ~~~ >[danger] ##### 優缺點 * 優點 ~~~ 1、觀察者和被觀察者是抽象耦合的 2、建立一套觸發機制。 ~~~ * 缺點 ~~~ 1、如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間 2、如果在觀察者和觀察目標之間有循環依賴的話,觀察目標會觸發它們之間進行循環調用,可能導致系統崩潰。 3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發生變化的,而僅僅只是知道觀察目標發生了變化。 ~~~ [另一篇參考鏈接](http://www.hmoore.net/cyyspring/vuejs/2083506) >[danger]使用場景 ~~~ 1、一個抽象模型有兩個方面,其中一個方面依賴于另一個方面。將這些方面封裝在獨立的對象中使它們可以各自獨立地改變和復用。 2、一個對象的改變將導致其他一個或多個對象也發生改變,而不知道具體有多少對象將發生改變,可以降低對象之間的耦合度。 3、一個對象必須通知其他對象,而并不知道這些對象是誰。 4、需要在系統中創建一個觸發鏈,A對象的行為將影響B對象,B對象的行為將影響C對象……,可以使用觀察者模式 創建一種鏈式觸發機制。 ~~~ >[success] # 前端觀察者(發布訂閱模式) [有案例說服的文章](https://juejin.im/post/5b125ad3e51d450688133f22#heading-0) ~~~ 1.當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。 比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。 2.實現一個觀察者模式代碼: 2.1. 首先定義誰充當發布者 2.2. 然后給發布者添加一個緩存列表,用于存放回調函數以便通知訂閱者 2.3.最后發布消息的時候,發布者會遍歷這個緩存列表,依次觸發里面存放的訂閱者回調函 (可選) 2.4.可以往回調函數里面填入一些參數,讓訂閱者可以接收到這些參數,訂閱者接收到這些參數后, 進行可以處理 3.簡單的說將代碼拆分成'觀察者(發布者)和被觀察者(訂閱者)' 4.站在需求業務角度來說,我個人的理解就是一些分散模塊共同組成整體模塊的時候可以使用,比喻一個不 恰當的例子,現在有個數據統計的頁面,里面有'條形圖','柱狀圖','餅狀圖'等一系列這種用來展示圖標模塊, 后臺的接口會將這些模塊一次返回,這時候我們可以創建一個發布者,這些數據展示模塊是訂閱者,去訂閱 了這個發布者,當數據請求接口,發布者變會觸發他的改變,通知下面的訂閱者去觸發自己展示效果 ~~~ * 如圖 ![](https://img.kancloud.cn/76/f2/76f214da488cd4643dab6a0ca25d9b04_1148x770.png) * 缺點 ~~~ 1.發布—訂閱模式雖然可以弱化對象之間的聯系,但如果過度使用的話,對象和對象之間的必要聯 系也將被深埋在背后,會導致程序難以跟蹤維護和理解。特別是有多個發布者和訂閱者嵌套到一 起的時候,要跟蹤一個 bug 不是件輕松的事情 ~~~ >[danger] ##### 書中的例子售樓處賣房子 ~~~ 1.場景:售樓處賣房子很多的想買房子的人來咨詢房子的事情,但是現在有些房子還需要等待最終的結果, 打算買房子的人就把自己的個人信息都給了售樓處的人,售樓處的人等這些房子有了消息,統一打電話 告訴打算房子人他們想要知道的消息,就不用每次都給來一趟售樓處來知道關于當前房子的事 2. 根據實現觀察者模式的代碼步驟來分析現狀我們需要寫的代碼結構: 2.1.需要一個發布者(售樓處) 2.2.一個用來記錄需要收到發布者發送消息的列表(主要記錄誰?記錄訂閱者) 2.3.當有關于房子信息的時候需要有一個方法用來遍歷剛才列表來通知訂閱者們收到消息 3.還是通過定義來理解: '當對象間存在一對多關系時,一個對象被修改時,則會自動通知它的依賴對象',像之前說的售樓處就是這個一, 這些客戶就是這些多,是當售樓處(發布者)這個一的'新樓盤推沒推出'的狀態改變了,來告訴這些訂閱者,也就是 買房子的用戶 ~~~ * 第一版代碼實現 ~~~ // -------這種將消息給了所有訂閱者 ------- // 發布--訂閱模式 // 售樓處的例子,售樓處工作人員 對應多個客戶,首先采集需要被通知的客戶, // 售樓處工作人員然后在需要的時候將消息發送給這些客戶 var salesOffices = {} // 定義售樓處 salesOffices.clientList = [] // 緩存列表,存放訂閱者的回調函數 salesOffices.listen = function (fn) { // 增加訂閱者 this.clientList.push(fn) // 訂閱的消息添加進緩存列表 } salesOffices.trigger = function () { // 發布消息 for(var i=0,fn;fn=this.clientList[i++];){ fn.apply(this,arguments) // 發布消息帶的參數 } } // 需要被通知的客戶給售樓處登記 salesOffices.listen(function (price, squareMeter) { console.log('價格='+price) console.log('平數='+squareMeter) }) // 需要被通知的客戶給售樓處登記 salesOffices.listen(function (price, squareMeter) { console.log('價格='+price) console.log('平數='+squareMeter) }) // 現在開盤了倒計時 ,到了就開盤 setTimeout(()=>{ salasOffice.tigger(2000,88) salasOffice.tigger(3000,87) },5000) ~~~ ~~~ 1.上面代碼打印結果是: 價格=200000 平數=88 價格=200000 平數=88 價格=200000 平數=87 價格=200000 平數=87 2.這段代碼出現了很奇妙的問題,第一個訂閱者想知道的是88平的房子多少錢一平,但實際運行后 把第二個訂閱者要知道的87平房價也告訴了。要解決的是通知對應的訂閱者他們想知道的消息 ~~~ * 解決 ~~~ 1.現在要做的就是改改進緩存列表存儲數據的格式,通過'key'和'value'的形式來進行通知時候區分 2.下面的代碼打印結果: 價格:200000 價格:300000 3.滿足我們剛才所想的只通知那些需要對應消息的人 ~~~ ~~~ var salesOffices = {} // 售樓處 salesOffices.clientList = {} // 緩存列表 salesOffices.listen = function (key, fn) { // 將需要接受相同類別的訂閱者保存起來 if(!this.clientList[key]){ this.clientList[key] = [] } this.clientList[key].push(fn) } salesOffices.trigger = function () { // 發布消息 var key = [].shift.call(arguments) fns = this.clientList[key] if(!fns || fns.length === 0){ // 不存在要通知的訂閱者 return false } for(var i=0,fn;fn = fns[i++];){ fn.apply(this,arguments) // 需要傳遞給訂閱者回調方法的參數 } } salesOffices.listen('squareMeter88',function (price) { console.log('價格:'+price) }) salesOffices.listen('squareMeter100',function (price) { console.log('價格:'+price) }) salesOffices.trigger('squareMeter88',200000) salesOffices.trigger('squareMeter100',300000) ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看