C#学习笔记-模板方法模式
题目:同学摘抄老师给的试卷并给出自己的对应的答案。
实现:
1 static void Main(string[] args) 2 { 3 Console.WriteLine("学生甲抄的试卷:"); 4 TestPaperA studentA = new TestPaperA(); 5 studentA.TestQuestion1(); 6 studentA.TestQuestion2(); 7 studentA.TestQuestion3(); 8 9 Console.WriteLine("学生乙抄的试卷:"); 10 TestPaperB studentB = new TestPaperB(); 11 studentB.TestQuestion1(); 12 studentB.TestQuestion2(); 13 studentB.TestQuestion3(); 14 15 Console.Read(); 16 } 17 18 /// <summary> 19 /// 两个学生分别摘抄了考卷问题,并写上了自己的答案。 20 /// </summary> 21 class TestPaperA 22 { 23 public void TestQuestion1() 24 { 25 Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 "); 26 Console.WriteLine("答案:b"); 27 } 28 public void TestQuestion2() 29 { 30 Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 "); 31 Console.WriteLine("答案:a"); 32 } 33 public void TestQuestion3() 34 { 35 Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 "); 36 Console.WriteLine("答案:c"); 37 } 38 } 39 40 class TestPaperB 41 { 42 public void TestQuestion1() 43 { 44 Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 "); 45 Console.WriteLine("答案:d"); 46 } 47 public void TestQuestion2() 48 { 49 Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 "); 50 Console.WriteLine("答案:b"); 51 } 52 public void TestQuestion3() 53 { 54 Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 "); 55 Console.WriteLine("答案:a"); 56 } 57 }
题目延伸1:根据上面实现的代码,可以看出来同学A和同学B都摘抄的同一份试卷,现在将单独的试卷放在他们单独对应的类里,可能出现的问题有两点,一是要是多人使用试卷就要在每个类里都写一遍相同的试卷,代码就会变得十分繁琐;二是每个人的试卷单独调用单独使用,可能会将试卷抄错,这样就没办法正确判断答案的正午了。
解析:
将题目单独放置在试卷类中,使用它的同学继承于他即可。
TestPaper类:
1 /// <summary> 2 /// 将考卷单独定义为一个类,这样将相同的部分提炼出来 3 /// 同时保证了不管多少同学使用这份考卷,大家的题目是一纸的,不会出现抄错题目的情况 4 /// </summary> 5 class TestPaper 6 { 7 public void TestQuestion1() 8 { 9 Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 "); 10 } 11 12 public void TestQuestion2() 13 { 14 Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 "); 15 } 16 17 public void TestQuestion3() 18 { 19 Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 "); 20 } 21 }
TestPaperA类和TestPaperB类:
1 class TestPaperA : TestPaper 2 { 3 //子类方法与父类方法关系:重写<override>,重构<new> 4 //重写父类方法时,必须指明被重写的方法时虚方法(virtual关键字) 5 //子类重载父类方法,必须给出关键字new 6 public new void TestQuestion1() 7 { 8 //base常用于,在派生类对象初始化时和基类进行通讯 9 //这里就是指父类TestPaper 10 base.TestQuestion1(); 11 Console.WriteLine("答案:B"); 12 } 13 14 public new void TestQuestion2() 15 { 16 base.TestQuestion2(); 17 Console.WriteLine("答案:b"); 18 } 19 20 public new void TestQuestion3() 21 { 22 base.TestQuestion3(); 23 Console.WriteLine("答案:b"); 24 } 25 } 26 27 class TestPaperB : TestPaper 28 { 29 public new void TestQuestion1() 30 { 31 base.TestQuestion1(); 32 Console.WriteLine("答案:b"); 33 } 34 35 public new void TestQuestion2() 36 { 37 base.TestQuestion2(); 38 Console.WriteLine("答案:b"); 39 } 40 41 public new void TestQuestion3() 42 { 43 base.TestQuestion3(); 44 Console.WriteLine("答案:b"); 45 } 46 }
题目延伸2:按道理除了题目外,“答案”几个字也是相同的,换言之,除了答案的abcd几个字以外,其他全部都是一样的。
实现:
1 class TestPaper 2 { 3 public void TestQueation1() 4 { 5 Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 "); 6 Console.WriteLine("答案:" + Answer1()); 7 } 8 9 protected virtual string Answer1() 10 { 11 return ""; 12 } 13 14 public void TestQuestion2() 15 { 16 Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 "); 17 Console.WriteLine("答案:" + Answer2()); 18 } 19 20 protected virtual string Answer2() 21 { 22 return ""; 23 } 24 25 public void TestQuestion3() 26 { 27 Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 "); 28 Console.WriteLine("答案:" + Answer3()); 29 } 30 31 protected virtual string Answer3() 32 { 33 return ""; 34 } 35 } 36 37 class TestPaperA : TestPaper 38 { 39 protected override string Answer1() 40 { 41 return "b"; 42 } 43 44 protected override string Answer2() 45 { 46 return "c"; 47 } 48 49 protected override string Answer3() 50 { 51 return "a"; 52 } 53 } 54 55 class TestPaperB : TestPaper 56 { 57 protected override string Answer1() 58 { 59 return "a"; 60 } 61 62 protected override string Answer2() 63 { 64 return "b"; 65 } 66 67 protected override string Answer3() 68 { 69 return "a"; 70 } 71 }
解析:
这就是模板方法模式
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
1 /** 2 * 模板方法模式 3 * 定义一个操作的算法的骨架,而将一些步骤延迟到子类中 4 * 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 5 */ 6 abstract class AbstractClass 7 { 8 //一些抽象行为,放到子类去实现 9 public abstract void PrimitiveOperation1(); 10 public abstract void PrimitiveOperation2(); 11 12 //模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,他们都推迟到子类实现 13 public void TemplateMethod() 14 { 15 PrimitiveOperation1(); 16 PrimitiveOperation2(); 17 Console.WriteLine(""); 18 } 19 } 20 21 class ConcreteClassA : AbstractClass 22 { 23 public override void PrimitiveOperation1() 24 { 25 Console.WriteLine("具体类A方法1实现"); 26 } 27 public override void PrimitiveOperation2() 28 { 29 Console.WriteLine("具体类A方法2实现"); 30 } 31 } 32 33 class ConcreteClassB : AbstractClass 34 { 35 public override void PrimitiveOperation1() 36 { 37 Console.WriteLine("具体类B方法1实现"); 38 } 39 public override void PrimitiveOperation2() 40 { 41 Console.WriteLine("具体类B方法2实现"); 42 } 43 }
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。
模板方法就是提供了一个很好的代码复用平台。
注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。
作者:可达鸭要进化
出处:http://www.cnblogs.com/Aries-rong/
本文版权归作者和博客园共有,欢迎转载,但是未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。