<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Javascript設計模式之我見:觀察者模式

      大家好!本文介紹觀察者模式及其在Javascript中的應用。

      模式介紹

      定義

      定義對象間一種一對多的依賴關系,使得每當一個對象改變狀態,則所有依賴于它的對象都會得到通知并被自動更新。

      類圖及說明

       

      Subject:主題\發布者

      能夠動態地增加、取消觀察者。它負責管理觀察者并通知觀察者。

      Observer:觀察者\訂閱者

      觀察者收到消息后,即進行update操作,對接收到的信息進行處理。

      ConcreteSubject:具體的主題\發布者

      定義主題自己的業務邏輯,同時定義對哪些事件進行通知。

      ConcreteObserver:具體的觀察者\訂閱者

      每個觀察者在接受到消息后的處理反應時不同的,各個觀察者有自己的處理邏輯。

      應用場景

      • 當一個對象的改變需要同時改變其它對象,而不知道具體有多少對象有待改變。
      • 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不希望這些對象是緊密耦合的。

      • 對象僅需要將自己的更新通知給其他對象而不需要知道其他對象的細節。 

      優點

      1. 支持簡單的廣播通信,自動通知所有已經訂閱過的對象。
      2. 頁面載入后目標對象很容易與觀察者存在一種動態關聯,增加了靈活性。
      3. 目標對象與觀察者之間的抽象耦合關系能夠單獨擴展以及重用。 

      缺點 

      1、  松偶合導致代碼關系不明顯,有時可能難以理解。

      2、  如果一個Subject被大量Observer訂閱的話,在廣播通知的時候可能會有效率問題。 

      觀察者模式在Javascript中的應用

      類圖及說明

      這里有兩個變化:

      1. ConcreteSubject與Subject的繼承關系改為委托關系。
      2. 刪除了Observer基類,直接將觀察者的update方法訂閱到Subject的events數組中。

      應用場景

      • 一個對象變化時觸發多個對象變化
      • 一個對象調用其他對象的方法,而又不想與之耦合

      示例

      現在是找工作的季節,大家都在忙著找工作。大神可以單槍匹馬秒殺各種offer,高富帥也有各種關系幫忙找工作。

      讓我們來看下高富帥是如何找工作的。

      類圖

       

      代碼

      GaoFuShuai

      function GaoFuShuai() {
          this._wang = new Wang();
      }
      
      GaoFuShuai.prototype.findJob = function () {
          console.log("高富帥開始找工作了");
          this._wang.help();
      };

      王哥

              function Wang() {
              }
      
              Wang.prototype.help = function () {
                  console.log("高富帥找工作啊,王哥來助你");
              }

      場景

      function main() {
          var gaofushuai = new GaoFuShuai();
      
          gaofushuai.findJob();
      }

      運行結果

      分析

      本設計有以下的缺點:

      1. 觀察者可能不止一個,如果增加李哥、張哥等觀察類,那就都要對應修改高富帥類,不符合開閉原則。
      2. 觀察者可能不僅僅要觀察高富帥的找工作情況,還要觀察高富帥的上學、娛樂等情況,這樣會有嚴重的耦合問題。

      使用觀察者模式

      現在使用觀察者模式來改進設計。

      類圖

      代碼

      Subject

         (function () {
              if (!Array.prototype.forEach) {
                  Array.prototype.forEach = function (fn, thisObj) {
                      var scope = thisObj || window;
                      for (var i = 0, j = this.length; i < j; ++i) {
                          fn.call(scope, this[i], i, this);
                      }
                  };
              }
      
              if (!Array.prototype.filter) {
                  Array.prototype.filter = function (fn, thisObj) {
                      var scope = thisObj || window;
                      var a = [];
                      for (var i = 0, j = this.length; i < j; ++i) {
                          if (!fn.call(scope, this[i], i, this)) {
                              continue;
                          }
                          a.push(this[i]);
                      }
                      return a;
                  };
              }
      
              var Subject = function () {
                  this._events = [];
              }
      
              Subject.prototype = (function () {
                  return {
                      //訂閱方法
                      subscribe: function (context, fn) {
                          if (arguments.length == 2) {
                              this._events.push({ context: arguments[0], fn: arguments[1] });
                          }
                          else {
                              this._events.push(arguments[0]);
                          }
                      },
                      //發布指定方法
                      publish: function (context, fn, args) {
                          var args = Array.prototype.slice.call(arguments, 2);    //獲得函數參數
                          var _context = null;
                          var _fn = null;
      
                          this._events.filter(function (el) {
                              if (el.context) {
                                  _context = el.context;
                                  _fn = el.fn;
                              }
                              else {
                                  _context = context;
                                  _fn = el;
                              }
      
                              if (_fn === fn) {
                                  return _fn;
                              }
                          }).forEach(function (el) {  //指定方法可能有多個
                                      el.apply(_context, args);       //執行每個指定的方法
                                  });
                      },
                      unSubscribe: function (fn) {
                          var _fn = null;
                          this._events = this._events.filter(function (el) {
                              if (el.fn) {
                                  _fn = el.fn;
                              }
                              else {
                                  _fn = el;
                              }
      
                              if (_fn !== fn) {
                                  return el;
                              }
                          });
                      },
                      //全部發布
                      publishAll: function (context, args) {
                          var args = Array.prototype.slice.call(arguments, 1);    //獲得函數參數
                          var _context = null;
                          var _fn = null;
      
                          this._events.forEach(function (el) {
                              if (el.context) {
                                  _context = el.context;
                                  _fn = el.fn;
                              }
                              else {
                                  _context = context;
                                  _fn = el;
                              }
      
                              _fn.apply(_context, args);       //執行每個指定的方法
                          });
                      },
                      dispose: function () {
                          this._events = [];
                      }
                  }
              })();
      
              window.Subject = Subject;
          })();
      View Code

      GaoFuShuai

      function GaoFuShuai() {
      }
      
      GaoFuShuai.prototype.findJob = function () {
          console.log("高富帥開始找工作了");
          window.subject.publishAll(null, "幫忙找工作");
      };
      GaoFuShuai.prototype.haveFun = function () {
          console.log("高富帥開始娛樂了");
          window.subject.publishAll(null, "幫忙找樂子");
      };

      王哥

      function Wang() {
      }
      
      Wang.prototype.help = function (actionStr) {
          console.log("王哥" + actionStr);
      };

      李哥

      function Li() {
      }
      
      Li.prototype.help = function (actionStr) {
          console.log("李哥" + actionStr);
      };

      場景

      function main() {
          var wang = new Wang(),
              li = new Li(),
              gaofushuai = new GaoFuShuai();
      
          window.subject = new Subject();
          window.subject.subscribe(wang.help);
          window.subject.subscribe(li.help);
      
          gaofushuai.findJob();
          gaofushuai.haveFun();
      }

      運行結果

      分析

      這樣就符合開閉原則了,被觀察者與觀察者也不再直接耦合了。如果想繼續增加觀察者,則只需對應修改main即可,被觀察者GaoFuShuai類不用修改。

      參考資料

      深入理解JavaScript系列(32):設計模式之觀察者模式
      《設計模式之禪》

      posted @ 2013-09-28 14:11  楊元超  閱讀(1399)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 人妻夜夜爽天天爽三区麻豆av| 国产成人亚洲欧美二区综合| 国产激情艳情在线看视频| 在国产线视频A在线视频| 国产精品不卡一区二区久久| 精品国产av一二三四区| 777奇米四色成人影视色区| 国产成人8x视频网站入口| 天天躁夜夜躁天干天干2020| 亚洲色www成人永久网址| 欧美精品在线观看| 欧洲码亚洲码的区别入口| 18禁视频一区二区三区| 全黄h全肉边做边吃奶视频| 日韩成人一区二区三区在线观看| 91精品91久久久久久| 一区二区三区久久精品国产| 欧美三级中文字幕在线观看 | www成人国产高清内射| 国产v亚洲v天堂a无码99| 国产av亚洲精品ai换脸电影 | 精品久久人人妻人人做精品| 亚洲国产婷婷综合在线精品| 国产精品视频一区二区亚瑟| 40岁大乳的熟妇在线观看| 蜜臀av一区二区三区不卡| 国产老头多毛Gay老年男| 久久久无码精品亚洲日韩蜜臀浪潮| 99久久99这里只有免费费精品| 亚洲欧美一区二区三区在线| 亚洲第一国产综合| 男女爽爽无遮挡午夜视频| 国产在线观看免费观看不卡| 另类专区一区二区三区| 罗城| 亚洲日本乱码熟妇色精品 | 国产精品一区二区三区四| 国产精品三级中文字幕| 四虎影视国产精品永久在线| 亚洲国产精品一区二区第一页| 中文字幕日韩一区二区不卡|