<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國際加速解決方案。 廣告
                # 模板方法模式深度解析(三) 4 鉤子方法的使用 模板方法模式中,在父類中提供了一個定義算法框架的模板方法,還提供了一系列抽象方法、具體方法和鉤子方法,其中鉤子方法的引入使得子類可以控制父類的行為。最簡單的鉤子方法就是空方法,代碼如下: ``` public virtual void Display() { } ``` 當然也可以在鉤子方法中定義一個默認的實現,如果子類不覆蓋鉤子方法,則執行父類的默認實現代碼。 另一種鉤子方法可以實現對其他方法進行約束,這種鉤子方法通常返回一個bool類型,即返回true或false,用來判斷是否執行某一個基本方法,下面通過一個實例來說明這種鉤子方法的使用。 某軟件公司欲為銷售管理系統提供一個數據圖表顯示功能,該功能的實現包括如下幾個步驟: (1) 從數據源獲取數據; (2) 將數據轉換為XML格式; (3) 以某種圖表方式顯示XML格式的數據。 該功能支持多種數據源和多種圖表顯示方式,但所有的圖表顯示操作都基于XML格式的數據,因此可能需要對數據進行轉換,如果從數據源獲取的數據已經是XML數據則無須轉換。 由于該數據圖表顯示功能的三個步驟次序是固定的,且存在公共代碼(例如數據格式轉換代碼),滿足模板方法模式的適用條件,可以使用模板方法模式對其進行設計。因為數據格式的不同,XML數據可以直接顯示,而其他格式的數據需要進行轉換,因此第(2)步“將數據轉換為XML格式”的執行存在不確定性,為了解決這個問題,可以定義一個鉤子方法IsNotXMLData()來對數據轉換方法進行控制。通過分析,該圖表顯示功能的基本結構如圖4所示: ![](http://img.my.csdn.net/uploads/201212/15/1355579556_7922.jpg) 圖4 數據圖表顯示功能結構圖 可以將公共方法和框架代碼放在抽象父類中,代碼如下: ``` //DataViewer.cs using System; namespace TemplateMethodSample { abstract class DataViewer { //抽象方法:獲取數據 public abstract void GetData(); //具體方法:轉換數據 public void ConvertData() { Console.WriteLine("將數據轉換為XML格式。"); } //抽象方法:顯示數據 public abstract void DisplayData(); //鉤子方法:判斷是否為XML格式的數據 public virtual bool IsNotXMLData() { return true; } //模板方法 public void Process() { GetData(); //如果不是XML格式的數據則進行數據轉換 if (IsNotXMLData()) { ConvertData(); } DisplayData(); } } } ``` 在上面的代碼中,引入了一個鉤子方法IsNotXMLData(),其返回類型為bool類型,在模板方法中通過它來對數據轉換方法ConvertData()進行約束,該鉤子方法的默認返回值為true,在子類中可以根據實際情況覆蓋該方法,其中用于顯示XML格式數據的具體子類XMLDataViewer代碼如下: ``` //XMLDataViewer.cs using System; namespace TemplateMethodSample { class XMLDataViewer : DataViewer { //實現父類方法:獲取數據 public override void GetData() { Console.WriteLine("從XML文件中獲取數據。"); } //實現父類方法:顯示數據,默認以柱狀圖方式顯示,可結合橋接模式來改進 public override void DisplayData() { Console.WriteLine("以柱狀圖顯示數據。"); } //覆蓋父類的鉤子方法 public override bool IsNotXMLData() { return false; } } } ``` 在具體子類XMLDataViewer中覆蓋了鉤子方法IsNotXMLData(),返回false,表示該數據已為XML格式,無須執行數據轉換方法ConvertData(),客戶端代碼如下: ``` //Program.cs using System; namespace TemplateMethodSample { class Program { static void Main(string[] args) { DataViewer dv; dv = new XMLDataViewer(); dv.Process(); Console.Read(); } } } ``` 該程序運行結果如下: ``` 從XML文件中獲取數據。 以柱狀圖顯示數據。 ``` 5 模板方法模式效果與適用場景 模板方法模式是基于繼承的代碼復用技術,它體現了面向對象的諸多重要思想,是一種使用較為頻繁的模式。模板方法模式廣泛應用于框架設計中,以確保通過父類來控制處理流程的邏輯順序(如框架的初始化,測試流程的設置等)。 5.1 模式優點 模板方法模式的主要優點如下: (1) 在父類中形式化地定義一個算法,而由它的子類來實現細節的處理,在子類實現詳細的處理算法時并不會改變算法中步驟的執行次序。 (2) 模板方法模式是一種代碼復用技術,它在類庫設計中尤為重要,它提取了類庫中的公共行為,將公共行為放在父類中,而通過其子類來實現不同的行為,它鼓勵我們恰當使用繼承來實現代碼復用。 (3) 可實現一種反向控制結構,通過子類覆蓋父類的鉤子方法來決定某一特定步驟是否需要執行。 (4) 在模板方法模式中可以通過子類來覆蓋父類的基本方法,不同的子類可以提供基本方法的不同實現,更換和增加新的子類很方便,符合單一職責原則和開閉原則。 5.2 模式缺點 模板方法模式的主要缺點如下: 需要為每一個基本方法的不同實現提供一個子類,如果父類中可變的基本方法太多,將會導致類的個數增加,系統更加龐大,設計也更加抽象,此時,可結合橋接模式來進行設計。 5.3 模式適用場景 在以下情況下可以考慮使用模板方法模式: (1) 對一些復雜的算法進行分割,將其算法中固定不變的部分設計為模板方法和父類具體方法,而一些可以改變的細節由其子類來實現。即:一次性實現一個算法的不變部分,并將可變的行為留給子類來實現。 (2) 各子類中公共的行為應被提取出來并集中到一個公共父類中以避免代碼重復。 (3) 需要通過子類來決定父類算法中某個步驟是否執行,實現子類對父類的反向控制。
                  <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>

                              哎呀哎呀视频在线观看