我接触的设计模式不多,在我接触不多的设计模式里,我觉的单例模式和模板方法模式是最好理解的两种设计模式了。
我们先通过文字简单的理解一下什么是模板方法模式,然后用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";
}
}
}