我接觸的設計模式不多,在我接觸不多的設計模式裏,我覺的單例模式和模板方法模式是最好理解的兩種設計模式了。
我們先通過文字簡單的理解一下什麼是模板方法模式,然後用C#代碼來寫一個小例子加深一下了解,當然所謂的加深是相對初學者的加深。
先從字面上理解一下什麼是模板方法設計模式,什麼是模板?
1、我想很多人都懂甚至接觸過,特別是對於大多數中學時考試成績不理想的同學包括我,在那時候總是希望優秀的同學完成的作業借我們抄一下,然後我們只是在自己的作業本上改上自己的名字和簡單的必要修改,那便可以交作業了,優秀同學已經寫好的作業我們可以看作是模板,簡單的必要修改和改名字這部份我們可以當作需要實現的虛類。
2、還有例如考英語試的時候,每個考生收到的試卷試題都是一樣的,這張試卷可以理解成是模板。填上試卷的答案是有可能不同的,那麼我們就不能將這部份歸到模板上去。所以模板是共有的相同的一部份。
3、再隨便的想一下,一臺電腦一定會有顯示器,鍵盤和主機,但不一定會有打印機,攝像頭,無線網卡……。那麼我們可以把顯示器,鍵盤和主機這部份歸劃成一部份,這部份就是模板。而打印機,攝像頭,無線網卡……這部份是不一定有的,所以不能劃作模板。
通過上面這幾個例子,不知道你對模板方法是不是有了一定了解。模板方法設計模試實現的原理和我們日常生活中的模板是有很大的相似之處的
那麼用程序應該怎麼實現?
我們會把相同的一部份提取出來作爲一個父類(這時父類就相同於一個模板),子類繼承父類後就擁有了這個父類全部的內容,可以說這時子類抄了這個模板,但是模板上面不同的內容怎麼改寫,例如我總不能把借來同學抄的作業連他的名字也抄在自己的作業本上吧,那樣老師一定一眼就看穿作業是抄來的。這時候可以通過在父類裏用virtual或者abstract寫一些方法,讓子類繼承父類後重寫這些virtual或者abstract的方法後就擁有了不同的一部份了。那麼也就是說可以寫上自己的名子,作一些簡單的修改了。。
我們來看一個例子,是《大話設計模式》書裏的一個例子,關於考試試卷的,每個考生收到試卷的題目是不變的,所以可以作爲模板,而答案是改變,那麼這部份可以寫成一個虛類(virtual)。看一下具體的代碼實現。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("學生甲抄的試卷:");
TestPaper studentA = new TestPaperA();
studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3();
Console.WriteLine();
Console.WriteLine("學生乙抄的試卷:");
TestPaper studentB = new TestPaperB();
studentB.TestQuestion1();
studentB.TestQuestion2();
studentB.TestQuestion3();
Console.Read();
}
}
class TestPaper
{
public void TestQuestion1()
{
Console.WriteLine(" 楊過得到,後來給了郭靖,煉成倚天劍、屠龍刀的玄鐵可能是[ ] a.球磨鑄鐵 b.馬口鐵 c.高速合金鋼 d.碳素纖維 ");
Console.WriteLine("答案:" + Answer1());
}
public void TestQuestion2()
{
Console.WriteLine(" 楊過、程英、陸無雙剷除了情花,造成[ ] a.使這種植物不再害人 b.使一種珍稀物種滅絕 c.破壞了那個生物圈的生態平衡 d.造成該地區沙漠化 ");
Console.WriteLine("答案:" + Answer2());
}
public void TestQuestion3()
{
Console.WriteLine(" 藍鳳凰的致使華山師徒、桃谷六仙嘔吐不止,如果你是大夫,會給他們開什麼藥[ ] a.阿司匹林 b.牛黃解毒片 c.氟哌酸 d.讓他們喝大量的生牛奶 e.以上全不對 ");
Console.WriteLine("答案:" + Answer3());
}
protected virtual string Answer1()
{
return "";
}
protected virtual string Answer2()
{
return "";
}
protected virtual string Answer3()
{
return "";
}
}
//學生甲抄的試卷
class TestPaperA : TestPaper
{
protected override string Answer1()
{
return "b";
}
protected override string Answer2()
{
return "c";
}
protected override string Answer3()
{
return "a";
}
}
//學生乙抄的試卷
class TestPaperB : TestPaper
{
protected override string Answer1()
{
return "c";
}
protected override string Answer2()
{
return "a";
}
protected override string Answer3()
{
return "a";
}
}
}