模板模式结构图:
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可冲抵英该算法的某些特定步骤
基本原型代码:
//抽象类
abstract class AbstractClass
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实现");
}
{
//一些抽象行为,放到子类中去实现
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实现");
}
}
//前台代码
static void Main(string[] args)
{
AbstractClass c;
c = new ConcreteClassA();
c.TemplateMethod();
c = new ConcreteClassB();
c.TemplateMethod();
Console.Read();
{
AbstractClass c;
c = new ConcreteClassA();
c.TemplateMethod();
c = new ConcreteClassB();
c.TemplateMethod();
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 TestPagerA:TestPaper{
protected override string Answer1()
{
return "b";
}
protected override string Answer2()
{
return "b";
}
protected override string Answer3()
{
return "b";
}
}
class TestPagerB : TestPaper
{
protected override string Answer1()
{
return "c";
}
protected override string Answer2()
{
return "c";
}
protected override string Answer3()
{
return "c";
}
}
{
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 TestPagerA:TestPaper{
protected override string Answer1()
{
return "b";
}
protected override string Answer2()
{
return "b";
}
protected override string Answer3()
{
return "b";
}
}
class TestPagerB : TestPaper
{
protected override string Answer1()
{
return "c";
}
protected override string Answer2()
{
return "c";
}
protected override string Answer3()
{
return "c";
}
}
//前台
static void Main(string[] args)
{
Console.WriteLine("学生甲抄的试卷:");
TestPaper studentA = new TestPagerA();
studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3();
Console.WriteLine("学生已抄的试卷:");
TestPaper studentB = new TestPagerB();
studentB.TestQuestion1();
studentB.TestQuestion2();
studentB.TestQuestion3();
Console.Read();
}
{
Console.WriteLine("学生甲抄的试卷:");
TestPaper studentA = new TestPagerA();
studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3();
Console.WriteLine("学生已抄的试卷:");
TestPaper studentB = new TestPagerB();
studentB.TestQuestion1();
studentB.TestQuestion2();
studentB.TestQuestion3();
Console.Read();
}
运行结果:
小结:
我们既然用了继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应要上升到父类去,而不是让每个子类都去重复。
当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常需要考虑用模板方法模式来处理。
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势;模板方法就是提供一个很好的代码服用平台。
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复的出现。我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。