<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國際加速解決方案。 廣告
                [TOC] # 模板方法模式 模板方法模式是一種只需使用繼承就可以實現的非常簡單的模式。 模板方法模式由兩部分構成: - 抽象父類:封裝了子類的算法框架,包括實現一些公共方法以及封裝子類中所有方法的執行順序。 - 具體實現的子類:通過基礎抽象父類,也繼承了整個算法結構,可以選擇重寫父類的方法。 假如一些平行的子類,各個子類直接有一些相同的行為,也有一些不同的行為。相同的行為可能會重復出現在各個子類之間,那這些相同的行為可以被搬到另一個單一的地方,模板方法模式就是為了解決這個問題而生的。 ```javascript var Beverage = function(); Beverage.prototype.boilWater = function(){ // 相同的方法 ... }; Beverage.prototype.brew = function(){ // 空方法,由子類進行重寫 ... }; Beverage.prototype.pourInCup = function(){ // 空方法,由子類進行重寫 ... }; Beverage.prototype.addCondiments = function(){ // 空方法,由子類進行重寫 ... }; Beverage.prototype.init = function(){ this.boilWater(); this.brew(); this.pourInCup(); this.addCondiments(); }; // 創建子類 var Coffee = new Beverage(); Coffee.prototype.brew = function(){ ... }; Coffee.prototype.pourInCup = function(){ ... }; Coffee.prototype.addCondiments = function(){ ... } var coffee = new Coffee(); conffee.init(); ``` 在上面的例子中,`Beverage.prototype.init`才是模板方法模式。該方法封裝了子類的算法框架,它作為一個算法模板,指導子類以何種順序去執行哪些方法。 ## 抽象類 模板方法模式是一種嚴重依賴抽象類的設計模式。在`Java`中有兩種類,一種是具體類,一種是抽象類。具體類可以被實例化,抽象類不能被實例化。就像說:我要一杯飲料,但是隨后還會被問到要什么飲料。而是要具體說咖啡。 抽象方法被聲明在抽象類中,抽象方法并沒有具體的實現過程,是一些“啞”方法。當子類繼承了這個抽象類時,必須重寫父類的抽象方法。 如果每個子類中都有一些同樣的具體實現方法,那這些方法也可以選擇放在抽象類中,這些方法就被稱為具體方法。 ## JavaScript沒有抽象類的缺點和解決方案 Java中編譯器會保證子類會重寫父類中的抽象方法,JavaScript中卻沒有進行這些檢查工作。編寫代碼時得不到任何形式的警告,完全寄托于程序員的記憶力和自覺性是很危險的。 有兩種解決方案 - 用鴨子類型來模擬接口類型檢查,以確保子類中確實重寫了父類的方法。但會帶來不必要的復雜性。 - 抽象父類中的方法直接拋出異常。實現簡單,付出的額外代價很少。但是得到錯誤信息時間太靠后。 ```javascript Beverage.prototype.brew = function(){ // 相同的方法 throw new Error('子類必須重寫brew方法') }; ``` ## 使用場景 大的方面就是架構師用于搭建項目的框架,程序員繼承框架開始填空。 比如在Web開發中的UI組件。(1)初始化一個div容器;(2)通過ajax請求拉取相應的數據;(3)把數據渲染到div容器里面,完成組件的構造;(4)通知用戶組件渲染完成。任何組件的構建(1)(4)相同。把4個方法都抽象到父類的模板方法,提供(1)(4)的具體實現。子類繼承后,重寫(2)(3); ## 鉤子方法 隔離變化的常見手段。 ## 好萊塢原則 允許底層組件將自己掛鉤到高層組件中,而高層組件會決定什么時候、以何種方式去使用這些底層組件。也就是“別調用我們,我們會調用你”。 當我們用模板方法模式編寫一個程序時,就意味著子類放棄了對自己的控制權,而是改為父類通知子類,哪些方法應該在什么時候被調用。作為子類只負責一些設計上的細節。 ## 真的需要繼承嗎 ```javascript var Beverage = function(param){ var boilWater = function(){...}; var brew = param.brew || function(){...}; var pourInCup = param.pourInCup || function(){...}; var F = function(){}; F.prototype.init = function(){ boilWater(); brew(); pourInCup(); } return F; }; // 創建子類 var Coffee = Beverage({ brew: function(){...},// 重寫 pourInCup: function(){...} }); var coffee = new Coffee(); coffee.init(); ``` 該模板方法依然封裝了子類的算法框架。
                  <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>

                              哎呀哎呀视频在线观看