模板方法模式(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
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...