模板方法模式(9)

来源:http://www.cnblogs.com/xiaomowang/archive/2017/01/19/6293560.html
-Advertisement-
Play Games

今天我們來講一下模板方法模式。 一、案例 我們在上中學的時候,會有這麼一種場景,老師在黑板上寫測試題,讓我們自己抄到紙上做。相信不少小伙伴們都經歷過這種歲月,想想還是很懷念的呢。這種做測試的方式,對當時的我們來講,有一個最致命的痛苦,就是這個題目會做,但是TM抄錯了題目了,擦擦擦。相信不少小伙伴肯定 ...


今天我們來講一下模板方法模式。

一、案例

我們在上中學的時候,會有這麼一種場景,老師在黑板上寫測試題,讓我們自己抄到紙上做。相信不少小伙伴們都經歷過這種歲月,想想還是很懷念的呢。這種做測試的方式,對當時的我們來講,有一個最致命的痛苦,就是這個題目會做,但是TM抄錯了題目了,擦擦擦。相信不少小伙伴肯定會遇到過這種情況。

好,下麵我們就用簡單的控制台應用程式來模擬一下這個場景

 1     /// <summary>
 2     /// 學生A抄的測試題
 3     /// </summary>
 4     class TestPaperA
 5     {
 6         //第一題
 7         public void TestQuestion1()
 8         {
 9             Console.WriteLine("第一題XXXXXXXXXXX");
10             Console.WriteLine("A");
11         }
12         //第二題
13         public void TestQuestion2()
14         {
15             Console.WriteLine("第二題XXXXXXXXXXX");
16             Console.WriteLine("A");
17         }
18         //第三題
19         public void TestQuestion3()
20         {
21             Console.WriteLine("第三題XXXXXXXXXXX");
22             Console.WriteLine("B");
23         }
24     }
25     /// <summary>
26     /// 學生B抄的測試題
27     /// </summary>
28     class TestPaperB
29     {
30         //第一題
31         public void TestQuestion1()
32         {
33             Console.WriteLine("第一題XXXXXXXXXXX");
34             Console.WriteLine("C");
35         }
36         //第二題
37         public void TestQuestion2()
38         {
39             Console.WriteLine("第二題XXXXXXXXXXX");
40             Console.WriteLine("A");
41         }
42         //第三題
43         public void TestQuestion3()
44         {
45             Console.WriteLine("第三題XXXXXXXXXXX");
46             Console.WriteLine("B");
47         }
48     }

客戶端:

 1         public static void Main()
 2         {
 3             Console.WriteLine("學生甲抄的試卷:");
 4             TestPaperA studentA = new MyTest.TestPaperA();
 5             studentA.TestQuestion1();
 6             studentA.TestQuestion2();
 7             studentA.TestQuestion3();
 8 
 9             Console.WriteLine("學生乙抄的試卷:");
10             TestPaperB studentB = new MyTest.TestPaperB();
11             studentB.TestQuestion1();
12             studentB.TestQuestion2();
13             studentB.TestQuestion3();
14 
15             Console.Read();
16         }

 上述代碼很好的描述了當前的這個場景,下麵呢,我們來看一下這種寫法有哪些問題。

①A B 兩個同學,除了個別的答案不一樣之外,其他的都是一樣的。

②如果老師突然要改題目,那麼 A B 兩個同學都需要修改。

③萬一有哪個同學把題目抄錯了,那豈不是很糟糕了。

二、演繹

1、第一步演繹

針對上面的幾個問題,我們來分析一下,感覺最好的效果就是,老師出一份試卷,多列印幾份,發給學生,只讓學生填寫答案就可以了。

好,這樣,我們可以抽象出一個父類(試題),分別讓A B 兩個繼承這個父類,就可以了。代碼如下:

 1     /// <summary>
 2     /// 父類 試卷
 3     /// </summary>
 4     class TestPaper
 5     {
 6         public void TestQuestion1()
 7         {
 8             Console.WriteLine("第一題XXXXXXXXXXXX");
 9         }
10         public void TestQuestion2()
11         {
12             Console.WriteLine("第二題XXXXXXXXXXXX");
13         }
14         public void TestQuestion3()
15         {
16             Console.WriteLine("第三題XXXXXXXXXXXX");
17         }
18     }
 1     /// <summary>
 2     /// 發給B的試卷
 3     /// </summary>
 4     class TestPaperA :TestPaper
 5     {
 6         //第一題
 7         public new  void TestQuestion1()
 8         {
 9             base.TestQuestion1();
10             Console.WriteLine("A");
11         }
12         //第二題
13         public new void TestQuestion2()
14         {
15             base.TestQuestion2();
16             Console.WriteLine("A");
17         }
18         //第三題
19         public new void TestQuestion3()
20         {
21             base.TestQuestion3();
22             Console.WriteLine("B");
23         }
24     }
25     /// <summary>
26     /// 發給B的試卷
27     /// </summary>
28     class TestPaperB:TestPaper
29     {
30         //第一題
31         public new void TestQuestion1()
32         {
33             base.TestQuestion1();
34             Console.WriteLine("C");
35         }
36         //第二題
37         public new void TestQuestion2()
38         {
39             base.TestQuestion2();
40             Console.WriteLine("A");
41         }
42         //第三題
43         public new void TestQuestion3()
44         {
45             base.TestQuestion3();
46             Console.WriteLine("B");
47         }
48     }

 客戶端

 1         public static void Main()
 2         {
 3             Console.WriteLine("學生甲抄的試卷:");
 4             TestPaperA studentA = new MyTest.TestPaperA();
 5             studentA.TestQuestion1();
 6             studentA.TestQuestion2();
 7             studentA.TestQuestion3();
 8 
 9             Console.WriteLine("學生乙抄的試卷:");
10             TestPaperB studentB = new MyTest.TestPaperB();
11             studentB.TestQuestion1();
12             studentB.TestQuestion2();
13             studentB.TestQuestion3();
14 
15             Console.Read();
16         }

嗯,我們看一下我們改進後的代碼還有什麼問題?

①每一個子類中都包含多個base. 還有 Console.WriteLine(),其實感覺除了ABCD答案之外,其他的都是重覆的。

既然用到了繼承,那麼,這個父類就應該成為一個模板,所有重覆的代碼都應該提升到父類中去。而不是去讓每個子類都去重覆。

 如何實現呢?下麵就是我們要將的模板方法模式了。

當我們完成某一細節層次上一致的過程或步驟,但更深層次的細節不太一樣的情況下,我們可以考慮使用模板方法模式了。

好,下麵我們來看一下模板方法模式的寫法:

 1     //抽象的父類
 2     abstract class AbstractClass
 3     {
 4         //一些抽象的行為,放到子類去實現
 5         public abstract void PrimitiveOperation1();
 6         public abstract void PrimitiveOperation2();
 7 
 8         //模板方法,給出了邏輯的骨架,邏輯的組成是一些相應的抽象操作,他們都到推遲到子類中去實現
 9         public void TemplageMethod()
10         {
11             PrimitiveOperation1();
12             PrimitiveOperation2();
13             Console.WriteLine("");
14         }
15     }
 1     //繼承 父類的子類 (實現父類中的方法)
 2     class  ConcreteClassA:AbstractClass
 3     {
 4         public override void PrimitiveOperation1()
 5         {
 6             Console.WriteLine("具體的A類方法1實現");
 7         }
 8 
 9         public override void PrimitiveOperation2()
10         {
11             Console.WriteLine("具體的A類方法2實現");
12         }
13     }
14 
15     //繼承父類的子類(實現父類中的方法)
16     class ConcreteClassB:AbstractClass
17     {
18         public override void PrimitiveOperation1()
19         {
20             Console.WriteLine("具體的B類方法1實現");
21         }
22 
23         public override void PrimitiveOperation2()
24         {
25             Console.WriteLine("具體的B類方法2實現");
26         }
27     }

客戶端:

 1         public static void Main()
 2         {
 3             AbstractClass c;
 4             c = new ConcreteClassA();
 5             c.TemplageMethod();
 6 
 7             c = new ConcreteClassB();
 8             c.TemplageMethod();
 9 
10             Console.Read();
11         }

嗯,好了,以上就是模板方法模式。我們可以按照以上的模式,將案例改寫成模板方法模式了。小伙伴們可以自行的修改一下。

okok,好了,今天就講到了里了,下一篇博文我們會講 外觀模式


本系列將持續更新,喜歡的小伙伴可以點一下關註和推薦,謝謝大家的支持。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ECMAScript語言的標準是由Netscape、Sun、微軟、Borland等公司基於JavaScript和JScript錘煉、定義出來的。 ECMAScript可以為不同種類的宿主環境提供核心的腳本編程能力。ECMAScript僅僅是一個描述,定義了腳本語言的所有屬性、方法和對象。 ...
  • Spring_屬性配置細節 1、若字面值包含特殊字元,可以使用<![CDATA[]] 把字面值包裹起來 例 : 2、ref屬性來建立bean之間的引用關係和級聯屬性賦值 2.1 定義User.java(見上一篇文章)和Manager.java Bean 2、2 配置spring xml文件 3、配置 ...
  • 本工作室專註開發南方湛江海南七星彩投註網站系統建設開發,出租,支持帶手機版投註,以及手機APP開發,安裝版本,蘋果版。 QQ私聊:2046 771739 演示圖: ...
  • 操作系統: CentOS 6.5_x64開發語言: Python 適用場景:程式異常退出後需要及時啟動的情況。 源碼地址: https://github.com/mike-zhang/processGuarder 原理 通過ps檢查進程是否存在,如果不存在則啟動 使用 ./processGuarde ...
  • maven-compiler-plugin 編譯Java源碼,一般只需設置編譯的jdk版本 maven-dependency-plugin 用於複製依賴的jar包到指定的文件夾里 maven-jar-plugin 打成jar時,設定manifest的參數,比如指定運行的Main class,還有依賴 ...
  • 今天在牛客網上做了一道題,題意就是求左旋轉字元串。我使用輾轉相除法解之,一次性AC通過。實話說,每次寫演算法一次性通過,甚至一點編譯錯誤都沒有,我覺得這就是對我最好的嘉獎。 題目描述: 彙編語言中有一種移位指令叫做迴圈左移(ROL),現在有個簡單的任務,就是用字元串模擬這個指令的運算結果。對於一個給定 ...
  • 本教程上接Django 1.10中文文檔-第一個應用Part2-模型和管理站點。我們將繼續開髮網頁投票這個應用,主要講如何創建一個對用戶開放的界面。 概覽 視圖是Django應用中的一“類”網頁,它通常使用一個特定的函數提供服務,並且具有一個特定的模板。例如,在博客應用中,可能有以下視圖: 博客首頁 ...
  • 【轉自:http://www.cnblogs.com/disheng2016/p/6266523.html】 maven下載jar包的預設倉庫是http://my.repository.com/repo/path速度較慢,通過配置國內鏡像提高下載速度 1.打開eclipse >Window >Pre ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...