一、概念
①、什么是模板模式?
定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
②、主要解决的问题?
一些方法通用,却在每一个子类都重写了这一方法。
③、如何解决?
将这些通用算法抽象出来。
④、优缺点?
优点:
1、封装不变部分,扩展可变部分;
2、提取公共代码,便于维护;
3、行为由父类控制,子类实现。
缺点:
每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
二、图
①、结构图
三、代码(从冗余到精简)
①、冗余代码类图
②、冗余代码
static void Main(string[] args)
{
Console.WriteLine("\n学生甲抄的试卷:"); //控制台内显示内容
TestPaperA studentA = new TestPaperA(); //实例化TestPaperA类,在内存中开辟一个空间
studentA.TestQuestion1(); //调取对象A的方法
studentA.TestQuestion2();
studentA.TestQuestion3();
Console.WriteLine("\n学生乙抄的试卷:");
TestPaperB studentB = new TestPaperB(); //实例化TestPaperB类,在内存中又开辟了一个空间
studentB.TestQuestion1(); //调取对象B的方法
studentB.TestQuestion2();
studentB.TestQuestion3();
Console.Read();
}
}
//学生甲抄的试卷
class TestPaperA
{
public void TestQuestion1() //问题一及答案
{
Console.WriteLine("海贼王中路飞的船上总共有几个成员[] a.7 b.8 c.9 d.10");
Console.WriteLine("答案:c");
}
public void TestQuestion2() //问题二及答案
{
Console.WriteLine("海贼王中顶上战争是哪一集[] a.105 b.205 c.405 d.459");
Console.WriteLine("答案:d");
}
public void TestQuestion3() //问题三及答案
{
Console.WriteLine("海贼王担任船医生的是哪一位[] a.乌索普 b.娜美 c.乔巴 d.路飞");
Console.WriteLine("答案:c");
}
}
//学生乙抄的试卷
class TestPaperB
{
public void TestQuestion1() //问题一及答案
{
Console.WriteLine("海贼王中路飞的船上总共有几个成员[] a.7 b.8 c.9 d.10");
Console.WriteLine("答案:c");
}
public void TestQuestion2() //问题二及答案
{
Console.WriteLine("海贼王中顶上战争是哪一集[] a.105 b.205 c.405 d.459");
Console.WriteLine("答案:a");
}
public void TestQuestion3() //问题三及答案
{
Console.WriteLine("海贼王担任船医生的是哪一位[] a.乌索普 b.娜美 c.乔巴 d.路飞");
Console.WriteLine("答案:d");
}
}
③、使用模板方法模式后的代码类图
④、使用模板方法模式的代码
class Program
{
static void Main(string[] args)
{
Console.WriteLine("\n学生甲抄的试卷:"); //控制台内显示内容
TestPaper studentA = new TestPaperA(); //体现多态,里氏代换原则:实例化TestPaper父类,在内存中开辟一个空间
studentA.TestQuestion1(); //调取对象A的方法
studentA.TestQuestion2();
studentA.TestQuestion3();
Console.WriteLine("\n学生乙抄的试卷:");
TestPaper studentB = new TestPaperB(); //实例化TestPaper父类,在内存中又开辟了一个空间
studentB.TestQuestion1(); //调取对象B的方法
studentB.TestQuestion2();
studentB.TestQuestion3();
Console.Read();
}
}
class TestPaper
{
public void TestQuestion1() //问题一及答案
{
Console.WriteLine("海贼王中路飞的船上总共有几个成员[] a.7 b.8 c.9 d.10");
Console.WriteLine("答案" + Answer1());
}
public void TestQuestion2() //问题二及答案
{
Console.WriteLine("海贼王中顶上战争是哪一集[] a.105 b.205 c.405 d.459");
Console.WriteLine("答案" + Answer2());
}
public void TestQuestion3() //问题三及答案
{
Console.WriteLine("海贼王担任船医生的是哪一位[] a.乌索普 b.娜美 c.乔巴 d.路飞");
Console.WriteLine("答案" + Answer3());
}
public virtual string Answer1() //虚拟答案方法,目的给继承的子类重写,每个子类的答案是不同的
{
return "";
}
public virtual string Answer2() //问题二具体答案
{
return "";
}
public virtual string Answer3() //问题三具体答案
{
return "";
}
}
//学生甲抄的试卷
class TestPaperA:TestPaper
{
public override string Answer1() //重写父类方法,得到具体对象甲的答案
{
return "b";
}
public override string Answer2()
{
return "d";
}
public override string Answer3()
{
return "a";
}
}
//学生乙抄的试卷
class TestPaperB:TestPaper
{
public override string Answer1() //具体对象乙重写父类答案方法
{
return "c";
}
public override string Answer2()
{
return "a";
}
public override string Answer3()
{
return "d";
}
}