<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          JavaScript常用設(shè)計(jì)模式

          共 8395字,需瀏覽 17分鐘

           ·

          2021-03-06 23:12


          點(diǎn)上方藍(lán)字關(guān)注公眾號(hào)「前端UpUp

          作者:holyZhengs

          來(lái)源:https://segmentfault.com/a/1190000015437592

          前言常用的設(shè)計(jì)模式

          1. 觀察者模式

          一個(gè)目標(biāo)對(duì)象維持著一系列依賴(lài)于它的對(duì)象,將有關(guān)狀態(tài)的任何變更自動(dòng)通知觀察者們。在觀察者模式中,觀察者需要直接訂閱目標(biāo)對(duì)象,觀察者與目標(biāo)對(duì)象之間有一定的依賴(lài)關(guān)系。有4個(gè)重要的概念

          • 目標(biāo)對(duì)象(被觀察者):維護(hù)一組觀察患者,提供管理觀察者的方法。
          • 觀察者:提供一個(gè)更新接口,用于收到通知時(shí),進(jìn)行更新
          • 具體目標(biāo)對(duì)象:代表具體的目標(biāo)對(duì)象
          • 具體觀察者:代表具體的觀察者
          // 目標(biāo)對(duì)象
          class Subject {
            constructor() {
              // 觀察者列表
              this.observers = []
            }
            addObserver(observer) {
              this.observers.push(observer)
            }
            removeObserver() {
              this.observers.pop()
            }
            notify() {
              this.observers.forEach(observer => {
                observer.update()
              })
            }
          }

          // 觀察者
          class Observer {
            constructor() {
              // 使用時(shí)會(huì)被具體update方法覆蓋
              this.update = function () {
                  // ..
              }
            }
          }
          // 具體目標(biāo)對(duì)象
          class currentSubject extends Subject {
            constructor() {
              super()    
            }
            // 其他自定義方法
            dosomething() {
              console.log('currentSubject change')
              this.notify()
            }
          }
          // 具體觀察者
          class currentObserver extends Observer {
              constructor() {
                  super()
              }
              // 重寫(xiě)update
              update() {
                  console.log('change!')
              }
          }
          // 訂閱
          let curSubject = new currentSubject()
          let curObserver = new currentObserver()
          curSubject.addObserver(curObserver)
          // 觸發(fā)
          curSubject.dosomething()
          // currentSubject change

          2.發(fā)布/訂閱模式

          發(fā)布訂閱模式可以說(shuō)是觀察這模式的一種變體,一種實(shí)現(xiàn)。它使用一個(gè)主題/事件通道,介于發(fā)布者和訂閱者之間,避免了發(fā)布者和訂閱者之間的依賴(lài)關(guān)系。

          class PubSub {
            constructor() {
          // 主題/事件通道
              this.topics = {}
            }
            publish(topic, args) {
              if (!this.topics[topic]) {
                return
              }
              let subscribers = this.topics[topic]
              subscribers.forEach(subscriber => {
                  subscriber.updata(args)
              })
            }
            subscribe(topic, subscriber ) {
              if (!this.topics[topic]) {
                this.topics[topic] = []
              }
              this.topics[topic].push(subscriber )
            }
          }

          let pubsub = new PubSub()

          pubsub.subscribe('one', subscriber )

          pubsub.publish('one''some args')

          3. 工廠模式

          工廠函數(shù)提供一個(gè)通用的接口來(lái)創(chuàng)建對(duì)象,我們可以指定我們希望創(chuàng)建的對(duì)象類(lèi)型,我們通知工廠函數(shù)需要什么類(lèi)型的對(duì)象并提供對(duì)應(yīng)的數(shù)據(jù),返回對(duì)應(yīng)的實(shí)例。

          class Car {
            constructor(options) {
              this.doors = options.doors || 4;
              this.state = options.state || "brand new";
              this.color = options.color || "silver";
            }
          }

          class Truck {
            constructor(options) {
              this.state = options.state || "used";
              this.wheelSize = options.wheelSize || "large";
              this.color = options.color || "blue";
            }
          }

          function vehicleFactory (options) {
            if (options.type === 'car') {
              return new Car(options)  
            } else {
              return new Truck(options)
            }
          }

          何時(shí)使用工廠模式

          • 當(dāng)我們的對(duì)象比較復(fù)雜的時(shí)候。
          • 當(dāng)我們需要根據(jù)不同情況創(chuàng)建不同對(duì)象實(shí)例的時(shí)候。
          • 當(dāng)我們需要?jiǎng)?chuàng)建許多相似對(duì)象的時(shí)候。

          缺點(diǎn)

          • 使用不當(dāng)會(huì)增加程序的復(fù)雜度

          4. 抽象工廠模式

          抽象工廠模式,將對(duì)象的實(shí)現(xiàn)細(xì)節(jié)抽離出來(lái)。適用于需要和多種對(duì)象一起工作的場(chǎng)景。

          class Truck {
            constructor(options) {
              this.state = options.state || "used";
              this.wheelSize = options.wheelSize || "large";
              this.color = options.color || "blue";
            }
          }

          class Car {
            constructor(options) {
              this.doors = options.doors || 4;
              this.state = options.state || "brand new";
              this.color = options.color || "silver";
            }
          }

          class AbstractFactory {
            constructor() {
              this.types = {}
            }
            registerFactory(type, factory) {
              this.types[type] = factory
            }
            getInstance(type, args) {
              let factory = this.types[type]
              if (factory) {
                return new factory(args)
              }
            }
          }

          let abstractFactory = new AbortController()
          abstractFactory.registerFactory('car', Car)
          abstractFactory.registerFactory('truck', Truck)

          abstractFactory.getInstance('car', options)
          abstractFactory.getInstance('truck', options)

          5. 單例模式

          單例模式限制一個(gè)類(lèi)只有一個(gè)實(shí)例化對(duì)象。

          class Obj(data) {
            // ....
          }
          // 利用閉包實(shí)現(xiàn)單例模式,確保obj類(lèi)只有一個(gè)實(shí)例
          function singleton (data) {
            var instance;
            return function () {
              if (!instance) {
                instance = new Obj(data)
              }
              return instance
            }
          }

          6. 中介者模式

          中介者模式就是提供一個(gè)中心點(diǎn)給系統(tǒng)不同組件之間進(jìn)行通信,降低系統(tǒng)組件之間的耦合程度。

          // 實(shí)現(xiàn)與發(fā)布/訂閱模式類(lèi)似

          觀察者模式和發(fā)布訂閱模式專(zhuān)注于維護(hù)目標(biāo)對(duì)象和觀察者之間的關(guān)系,當(dāng)主題對(duì)象發(fā)送變化時(shí),通知所有對(duì)改主題感興趣的觀察者。而中介者模式的話(huà),專(zhuān)注于限制對(duì)象的通信必須通過(guò)中介者來(lái)通信。兩者都提倡松耦合。

          7. 裝飾者模式

          裝飾者模式,通過(guò)一個(gè)裝飾類(lèi)對(duì)現(xiàn)有動(dòng)態(tài)添加行為,以及對(duì)原有行為進(jìn)行裝飾。

             // o為已有對(duì)象
              var M20 = function(o){    // 這里定義一個(gè)裝飾類(lèi)
                  var str = '20多歲的時(shí)候,';
                  // o是傳入的對(duì)象,調(diào)用傳入對(duì)象的方法,加以裝飾
                  this.eat = function(){
                      return str + o.eat()+",肥得很!";
                  };
                  this.drink = function(){
                      return str + o.drink()+",就是個(gè)水桶!";
                  };
                  this.coding = function(){
                      return str + o.coding()+",代碼又寫(xiě)得撇!";
                  };
              }
              alert(new M20(david).eat());    // 20多歲的時(shí)候,大衛(wèi)是個(gè)大胖子,一天只曉得吃,肥得很!
              alert(new M20(david).drink());    // 20多歲的時(shí)候,大衛(wèi)除了吃就是喝,就是個(gè)水桶!
              alert(new M20(david).coding());    // 20多歲的時(shí)候,寫(xiě)代碼吧,大衛(wèi),代碼又寫(xiě)得撇!

          8. 適配器模式

          使用一個(gè)新的接口對(duì)現(xiàn)有的接口進(jìn)行包裝,處理數(shù)據(jù)與接口的不匹配。

          function api (x1, x2, x3) {
            console.log(x1 + x2 + x3);  // 用console.log來(lái)模擬接口的相關(guān)操作
          }

          var data = {
            a: '我',
            b: '很',
            c: '帥'
          }

          function adapterApi (o) {
            // 通過(guò)適配器函數(shù)來(lái)調(diào)用目的api
            api(o.a, o.b, o.c);


          adapterApi(data);
          // 我很帥

          學(xué)習(xí)資料:

          聽(tīng)飛狐聊JavaScript設(shè)計(jì)模式系列

          javascript設(shè)計(jì)模式

           感謝大家

          1. 關(guān)注「前端UpUp」,分享精選面試熱點(diǎn)文章。

          2. 加我好友,一起討論算法,2021一起UpUp。

          點(diǎn)個(gè)在看支持我吧


          瀏覽 30
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操鼻素材大全在线 | 无码一区二区三 | 国产灌醉 | 久久青青草香蕉手机视频在线 | 自拍偷拍五月婷婷 |