C#学习笔记-模板方法模式
题目:同学摘抄老师给的试卷并给出自己的对应的答案。
实现:
static void Main(string[] args)
{
Console.WriteLine("学生甲抄的试卷:");
TestPaperA studentA = new TestPaperA();
studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3(); Console.WriteLine("学生乙抄的试卷:");
TestPaperB studentB = new TestPaperB();
studentB.TestQuestion1();
studentB.TestQuestion2();
studentB.TestQuestion3(); Console.Read();
} /// <summary>
/// 两个学生分别摘抄了考卷问题,并写上了自己的答案。
/// </summary>
class TestPaperA
{
public void TestQuestion1()
{
Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");
Console.WriteLine("答案:b");
}
public void TestQuestion2()
{
Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 ");
Console.WriteLine("答案:a");
}
public void TestQuestion3()
{
Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 ");
Console.WriteLine("答案:c");
}
} class TestPaperB
{
public void TestQuestion1()
{
Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");
Console.WriteLine("答案:d");
}
public void TestQuestion2()
{
Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 ");
Console.WriteLine("答案:b");
}
public void TestQuestion3()
{
Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 ");
Console.WriteLine("答案:a");
}
}
题目延伸1:根据上面实现的代码,可以看出来同学A和同学B都摘抄的同一份试卷,现在将单独的试卷放在他们单独对应的类里,可能出现的问题有两点,一是要是多人使用试卷就要在每个类里都写一遍相同的试卷,代码就会变得十分繁琐;二是每个人的试卷单独调用单独使用,可能会将试卷抄错,这样就没办法正确判断答案的正午了。
解析:
将题目单独放置在试卷类中,使用它的同学继承于他即可。
TestPaper类:
/// <summary>
/// 将考卷单独定义为一个类,这样将相同的部分提炼出来
/// 同时保证了不管多少同学使用这份考卷,大家的题目是一纸的,不会出现抄错题目的情况
/// </summary>
class TestPaper
{
public void TestQuestion1()
{
Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");
} public void TestQuestion2()
{
Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 ");
} public void TestQuestion3()
{
Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 ");
}
}
TestPaperA类和TestPaperB类:
class TestPaperA : TestPaper
{
//子类方法与父类方法关系:重写<override>,重构<new>
//重写父类方法时,必须指明被重写的方法时虚方法(virtual关键字)
//子类重载父类方法,必须给出关键字new
public new void TestQuestion1()
{
//base常用于,在派生类对象初始化时和基类进行通讯
//这里就是指父类TestPaper
base.TestQuestion1();
Console.WriteLine("答案:B");
} public new void TestQuestion2()
{
base.TestQuestion2();
Console.WriteLine("答案:b");
} public new void TestQuestion3()
{
base.TestQuestion3();
Console.WriteLine("答案:b");
}
} class TestPaperB : TestPaper
{
public new void TestQuestion1()
{
base.TestQuestion1();
Console.WriteLine("答案:b");
} public new void TestQuestion2()
{
base.TestQuestion2();
Console.WriteLine("答案:b");
} public new void TestQuestion3()
{
base.TestQuestion3();
Console.WriteLine("答案:b");
}
}
题目延伸2:按道理除了题目外,“答案”几个字也是相同的,换言之,除了答案的abcd几个字以外,其他全部都是一样的。
实现:
class TestPaper
{
public void TestQueation1()
{
Console.WriteLine(" 杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是[ ] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维 ");
Console.WriteLine("答案:" + Answer1());
} protected virtual string Answer1()
{
return "";
} public void TestQuestion2()
{
Console.WriteLine(" 杨过、程英、陆无双铲除了情花,造成[ ] a.使这种植物不再害人 b.使一种珍稀物种灭绝 c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化 ");
Console.WriteLine("答案:" + Answer2());
} protected virtual string Answer2()
{
return "";
} public void TestQuestion3()
{
Console.WriteLine(" 蓝凤凰的致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[ ] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对 ");
Console.WriteLine("答案:" + Answer3());
} 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 "a";
} protected override string Answer2()
{
return "b";
} protected override string Answer3()
{
return "a";
}
}
解析:
这就是模板方法模式
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
/**
* 模板方法模式
* 定义一个操作的算法的骨架,而将一些步骤延迟到子类中
* 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
*/
abstract class AbstractClass
{
//一些抽象行为,放到子类去实现
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2(); //模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作,他们都推迟到子类实现
public void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
Console.WriteLine("");
}
} class ConcreteClassA : AbstractClass
{
public override void PrimitiveOperation1()
{
Console.WriteLine("具体类A方法1实现");
}
public override void PrimitiveOperation2()
{
Console.WriteLine("具体类A方法2实现");
}
} class ConcreteClassB : AbstractClass
{
public override void PrimitiveOperation1()
{
Console.WriteLine("具体类B方法1实现");
}
public override void PrimitiveOperation2()
{
Console.WriteLine("具体类B方法2实现");
}
}
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。
模板方法就是提供了一个很好的代码复用平台。
注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。
C#学习笔记-模板方法模式的更多相关文章
- 《Head First 设计模式》学习笔记——模板方法模式
模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以详细方法以及详细构造函数的形式实现.然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类能够以不同的方式实现这些抽象方法,从而对剩余的逻辑有 ...
- 《Head first设计模式》学习笔记 – 迭代器模式
<Head first设计模式>学习笔记 – 迭代器模式 代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 爆炸性新闻:对象村餐厅和对象村煎饼屋合并了!真是个 ...
- Java设计模式学习记录-模板方法模式
前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...
- 设计模式学习之模板方法模式(TemplateMethod,行为型模式)(9)
一.什么是模板方法模式 Template Method模式也叫模板方法模式,是行为模式之一,它把具有特定步骤算法中的某些必要的处理委让给抽象方法,通过子类继承对抽象方法的不同实现改变整个算法的行为. ...
- Android源码学习之模板方法模式应用
一.模板方法模式定义 模板方法模式定义: defines the skeleton of an algorithm in a method, deferring some steps to subcl ...
- 《Head First 设计模式》学习笔记——状态模式
在软件开发过程中.应用程序可能会依据不同的情况作出不同的处理. 最直接的解决方式是将这些全部可能发生的情况全都考虑到.然后使用if... ellse语句来做状态推断来进行不同情况的处理. 可是对复杂状 ...
- 学习笔记——解释器模式Interpreter
解释器模式,其实就是编译原理中的语法解释器,如果用在项目中,可以用于实现动态脚本的解析,也就是说项目可以支持用户脚本扩展. 但实际上,这种运行时解释,效率很慢,如果不是很需要的话,不建议使用. 一种简 ...
- [学习笔记] Dispose模式
Dispose模式是.NET中很基础也很重要的一个模式,今天重新复习一下相关的东西并记录下来. 什么是Dispose模式? 什么时候我们该为一个类型实现Dispose模式 使用Dispose模式时应该 ...
- jquery学习笔记---插件开发模式和结构
JQuery插件开发http://www.cnblogs.com/damonlan/archive/2012/04/06/2434460.html github教程:https://github.co ...
随机推荐
- Linux磁盘及文件系统(二)Linux下磁盘命名和分区
在为主机添加硬盘之前,首先需要了解Linux系统下对硬盘和分区的命令方法 一.磁盘命名 Linux下对SCSI和SATA设备是以sd命名的,第一个SCSI设备是sda,第二个是sdb....以此类推. ...
- tf入门-卷积步长strides参数的具体解释
conv1 = tf.nn.conv2d(input_tensor,conv1_weights,strides=[1,1,1,1],padding='SAME') 这是一个常见的卷积操作,其中stri ...
- Python 魔法方法查询表 -- 总结篇
据说,Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切. 他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个, ...
- docker 实例设置自动重启
yaml格式太严格了,每个冒号后面都必须带有空格在linux中./代表当前目录,属于相对路径../代表上一级目录,属于相对路径/代表根目录,/开头的文件都是绝对路径./configure的意思是执行当 ...
- Centos7.4下安装Mysql8.0.15
一.下载Mysql Mysql下载地址:https://dev.mysql.com/downloads/mysql/ 二.卸载Linux自带的mariadb 安装Mysql之前需要卸载maria ...
- hive一些基本用法
1.hive中的数据库表的类型有两种,一种是managed,一种是external :managed表类型是指传入的数据放在hive默认的储存位置下,而external 表类型可以将数据 放在任意的 ...
- jQuery EasyUI Datagrid组件的完整的基础DOM结构
标题可能有点长,什么叫“完整的基础DOM结构”,这里“基础”的意思是指这个结构不依赖具体数据,不依赖Datagrid的view属性,只要存在Datagrid实例就会存在这样的基础DOM结构:而“完整” ...
- 安卓手机移动端Web开发调试之Chrome远程调试(Remote Debugging)
一.让安卓打debug模式的apk包 二.将电脑中的chrome升级到最新版本,在chrome浏览器地址栏中输入chrome://inspect/#devices: 在智能手机还未普及时,移动设备的调 ...
- vue.js - axios Get、Post方法传参给 .net core webapi。
一:axios中是 Get请求: 1:在vue项目中通过params属性携带数据: let _self = this; axios({ method:'get', url:'http://localh ...
- (转)总结之:CentOS 6.5 MySQL数据库的基础以及深入详解
总结之:CentOS 6.5 MySQL数据库的基础以及深入详解 原文:http://tanxw.blog.51cto.com/4309543/1395539 前言 早期MySQL AB公司在2009 ...