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 ...
随机推荐
- redhat linux elk命令
安装es后不能启动原因在elasticsearch.yml中加如下两个配置: bootstrap.memory_lock: falsebootstrap.system_call_filter: fal ...
- java使用Redis6--sentinel单点故障主从自动切换
Redis SentinelSentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中 一.Sentinel作用:1):Master状态检测 2 ...
- 【微信小程序】——rpx、px、rem等尺寸间关系浅析
最近开发微信小程序,在写样式表的时候发现用PX的效果不太理想,而官方文档用rpx来做响应式布局单位,就仔细研究了下,在此做个小总结: 这里先引用官方定义的尺寸单位‘rpx’:可以根据屏幕宽度进行自适应 ...
- [转] LVM分区在线扩容
[转] LVM分区在线扩容 在线扩容的这台服务器,LV分区格式为xfs,原大小1.2TB.增加了一块硬盘,大小为1.8TB. fdisk /dev/cciss/c0d1 # 创建分区,并指定分区类型为 ...
- IDEA 引入外部jar包 pom 配置,防止打包失败
1. <!--添加外部依赖--> <dependency> <groupId>Ice</groupId> ...
- 2016级算法期末上机-H.难题·AlvinZH's Fight with DDLs III
1119 AlvinZH's Fight with DDLs III 思路 难题,最小点覆盖. 分析题意,某一个任务,既可以在笔记本A的 \(a\) 模式下完成,也可以在笔记本B的 \(b\) 模式下 ...
- (Lua) C++ 寫函式,Lua 呼叫使用
C++ 裡頭寫一個 Function 但是透過 Lua 提供input參數並且回傳結果給Lua 輸出的辦法. Lua 檔案 , , ) print("ave : ", ave, & ...
- Windows开发经验 - Visual Studio 2017
1. 调试子进程 Visual Studio 2017及更早的版本原生不支持调试子进程,不确定未来是否会支持.可以通过官方插件让Visual Studio能够调试子进程. https://market ...
- 【文档】二、Binlog结构和内容概述
binlog是一系列文件,这些文件包含了Mysql服务实例中数据的变化. binlog包含一系列二进制日志文件,还包含一个索引文件. 每个日志文件包含了一个4字节的魔法数,后面跟着描述数据变化的事件内 ...
- CentOS6.4安装OpenSSL
1.下载 wget https://www.openssl.org/source/openssl-1.0.2h.tar.gz 2.解压 tar zxf openssl-1.0.2h.tar.gz cd ...