1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

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

        共 8395字,需瀏覽 17分鐘

         ·

        2021-03-06 23:12


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

        作者:holyZhengs

        來源:https://segmentfault.com/a/1190000015437592

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

        1. 觀察者模式

        一個(gè)目標(biāo)對(duì)象維持著一系列依賴于它的對(duì)象,將有關(guān)狀態(tài)的任何變更自動(dòng)通知觀察者們。在觀察者模式中,觀察者需要直接訂閱目標(biāo)對(duì)象,觀察者與目標(biāo)對(duì)象之間有一定的依賴關(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()
            }
            // 重寫update
            update() {
                console.log('change!')
            }
        }
        // 訂閱
        let curSubject = new currentSubject()
        let curObserver = new currentObserver()
        curSubject.addObserver(curObserver)
        // 觸發(fā)
        curSubject.dosomething()
        // currentSubject change

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

        發(fā)布訂閱模式可以說是觀察這模式的一種變體,一種實(shí)現(xiàn)。它使用一個(gè)主題/事件通道,介于發(fā)布者和訂閱者之間,避免了發(fā)布者和訂閱者之間的依賴關(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è)通用的接口來創(chuàng)建對(duì)象,我們可以指定我們希望創(chuàng)建的對(duì)象類型,我們通知工廠函數(shù)需要什么類型的對(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é)抽離出來。適用于需要和多種對(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è)類只有一個(gè)實(shí)例化對(duì)象。

        class Obj(data) {
          // ....
        }
        // 利用閉包實(shí)現(xiàn)單例模式,確保obj類只有一個(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ā)布/訂閱模式類似

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

        7. 裝飾者模式

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

           // o為已有對(duì)象
            var M20 = function(o){    // 這里定義一個(gè)裝飾類
                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()+",代碼又寫得撇!";
                };
            }
            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í)候,寫代碼吧,大衛(wèi),代碼又寫得撇!

        8. 適配器模式

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

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

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

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


        adapterApi(data);
        // 我很帥

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

        聽飛狐聊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)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            在线观看成人无码 | 国产性xxxx | 波多野结衣伦理片 | 好爽还要再深点好硬 | 婷婷综合激情 | 骚逼少妇| 亚洲AⅤ欧美AⅤ | 国产精品视频播放豆花网站 | 成人开心激情 | 黄色超碰 |