<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                >[success] # 狀態模式 ~~~ 1.GoF 中 對狀態模式的定義: 允許一個對象在其內部狀態改變時改變它的行為,對象看起來似乎修改了它的類。 2.設計狀態模式的思路:當我們設計類,給一個類做封裝的時候一般都會優 '先封裝對象的行為', 而'不是對象的狀態'。'狀態模式'中'剛好相反',狀態模式的關鍵是把事物的'每種狀都封裝成單獨的類', 跟'狀態有關的行為'都被'封裝在這個類的內部'。 3.簡單的的說: 3.1.'是將狀態封裝成獨立的類,并 將請求委托給當前的狀態對象,當對象的內部狀態改變時,會帶來不同的行為變化' 3.2.'是從客戶的角度來看,我們使用的對象,在不同的狀態下具有截然不同的行為,這 個對象看起來是從不同的類' '中實例化而來的,實際上這是使用了委托的效果' 3.3.還要注意他遵循的方式屬于'是循規蹈矩的 A→B→C→A' ~~~ >[info] ## 書中的開關燈案例 ~~~ 1.通過狀態模式概念的解釋'行為是基于它的狀態改變的。這種類型的設計模式屬于行為型模式', 就可以理解狀態控制行為是這模式一個特點,生活中最常見的這種案例就是開關燈,通過改變 開關的狀態來改變燈的效果 ~~~ >[danger] ##### 傳統意義上的開關燈代碼實現 ~~~ 1.我么創建一個燈的對象,給這個對象增加一個初始化方法叫'init',這個方法主要用來創建開關 ,這個對象還有一個屬性'state'用來記錄當前開關的狀態從而控制燈 ~~~ ~~~ var Light = function () { this.state = 'off' this.button = null } // 初始化按鈕 Light.prototype.init = function () { var button = document.createElement('button'), self = this button.innerHTML = '開關' this.button = document.body.appendChild(button) this.button.onclick = function () { self.buttonWasPressed() } } // 按鈕點擊事件 Light.prototype.buttonWasPressed = function () { if(this.state === 'off'){ console.log('開燈') this.state = 'on' }else if (this.state === 'on'){ console.log('關燈') this.state = 'off' } } var light = new Light() light.init() ~~~ >[danger] ##### 這樣的缺點 ~~~ 1.這樣的缺點就是,以后如果這個燈可以調節燈光的強弱,問題來了我們的'buttonWasPressed ' 方法里面可能會充斥著大量的和狀態有關的'if - else' 判斷,就會這樣: Light.prototype.buttonWasPressed = function(){ if ( this.state === 'off' ){ console.log( '弱光' ); this.state = 'weakLight'; }else if ( this.state === 'weakLight' ){ console.log( '強光' ); this.state = 'strongLight'; }else if ( this.state === 'strongLight' ){ console.log( '關燈' ); this.state = 'off'; } }; 2.'buttonWasPressed' 方法是違反開放?封閉原則的,每次新增或者修改 light 的狀態, 都需要改動 buttonWasPressed 方法中的代碼 3.狀態的切換非常不明顯,僅僅表現為對 state 變量賦值,比如 this.state = 'weakLight'。 在實際開發中,這樣的操作很容易被程序員不小心漏掉。我們也沒有辦法一目了然地明 白電燈'一共有多少種狀態' ~~~ >[danger] ##### 通過狀態模式來寫開關燈 ~~~ 1.我們做的是根據狀態來封裝我們的類,把這個請求委托給當前的狀態對象即可,該狀態對象 會負責渲 染它自身的行為,引用書中的兩個圖做說明 ~~~ * 狀態 ![](https://img.kancloud.cn/7b/ab/7babf55d0d39a750d227e079a6ca75b1_488x468.png) * 通過按鈕去和這樣狀態連接到一起 ![](https://img.kancloud.cn/29/05/2905de6fa10fee51765167585c8e9698_638x270.png) >[danger] ##### 狀態模式開關燈的代碼實現 * 三種狀態封裝成類 ~~~ // 根據現在三種狀態封裝的類依次是 // 'OffLightState' -- 關燈狀態 // 'WeakLightState' -- 弱光狀態 // 'StrongLightState' -- 強光狀態 // OffLightState: var OffLightState = function( light ){ this.light = light; }; OffLightState.prototype.buttonWasPressed = function(){ console.log( '弱光' ); // offLightState 對應的行為 this.light.setState( this.light.weakLightState ); // 切換狀態到 weakLightState }; // WeakLightState: var WeakLightState = function( light ){ this.light = light; }; WeakLightState.prototype.buttonWasPressed = function(){ console.log( '強光' ); // weakLightState 對應的行為 this.light.setState( this.light.strongLightState ); // 切換狀態到 strongLightState }; // StrongLightState: var StrongLightState = function( light ){ this.light = light; }; StrongLightState.prototype.buttonWasPressed = function(){ console.log( '關燈' ); // strongLightState 對應的行為 this.light.setState( this.light.offLightState ); // 切換狀態到 offLightState }; ~~~ * 燈的類來調度狀態 ~~~ 1.不再使用一個字符串來記錄當前的狀態,而是使用'狀態對象'。在 Light 類的構造函數里 為每個狀態類都創建一個狀態對象,這樣一來我們可以 很明顯地看到電燈一共有多少種狀態 2.使用'setState '方法,狀態對象可以通過這個方法來切換 light對象的狀態,來替代'if-else'語句 都在狀態類中調用這個方法 3.以后擴展的話只需要在構造函數中加上對應的狀態擴展類即可 ~~~ ~~~ var Light = function(){ this.offLightState = new OffLightState( this ); this.weakLightState = new WeakLightState( this ); this.strongLightState = new StrongLightState( this ); this.button = null; }; Light.prototype.setState = function( newState ){ this.currState = newState; }; Light.prototype.init = function(){ var button = document.createElement( 'button' ), self = this; this.button = document.body.appendChild( button ); this.button.innerHTML = '開關'; this.currState = this.offLightState; // 設置當前狀態 this.button.onclick = function(){ self.currState.buttonWasPressed(); } }; ~~~ >[danger] ##### 現在模板模式的問題 ~~~ 1.js 不像java有接口的概念,那么我們就要保證一個問題就是上面的代碼中每個根據狀態寫的類, 都需要去實現'buttonWasPressed'方法這種重復工作很容易出錯,但是可以使用'模板方法模式' 方式拋出異常 ~~~
                  <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>

                              哎呀哎呀视频在线观看