设计模式之模板方法模式
读书那会,我们经常要抄题目,从黑板上抄,从同学笔记那里抄,说实话,我就不喜欢这种学习方式,容易抄错题目。
我们来代码实现一下:
public class TestPaper1 { //试题1 public void testQuestion1(){ System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是【】a 球磨铸铁 b马口铁 c高速合金钢 d碳素纤维"); System.out.println("答案: b"); } //试题2 public void testQuestion2(){ System.out.println("杨过、程英、陆无双铲除了情花,造成【】a 使这种植物不再害人 b使一种珍惜物种灭绝 c破坏了生物圈的生态平衡 d造成该地区沙漠化"); System.out.println("答案: a"); } }
public class TestPaper2 { //试题1 public void testQuestion1(){ System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是【】a 球磨铸铁 b马口铁 c高速合金钢 d碳素纤维"); System.out.println("答案: d"); } //试题2 public void testQuestion2(){ System.out.println("杨过、程英、陆无双铲除了情花,造成【】a 使这种植物不再害人 b使一种珍惜物种灭绝 c破坏了生物圈的生态平衡 d造成该地区沙漠化"); System.out.println("答案: b"); } }
public class Test { public static void main(String[] args) { // TODO Auto-generated method stub TestPaper1 t1 = new TestPaper1(); t1.testQuestion1(); t1.testQuestion2(); TestPaper2 t2 = new TestPaper2(); t2.testQuestion1(); t2.testQuestion2(); } }
两份题目非常类似,除了答案不同。但如果一人抄错题目,那后面的人都会出错,这真实糟糕至极。那有没有更好点的实现方式呢?
第二版:
public class TestPaper { //试题1 public void testQuestion1(){ System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是【】a 球磨铸铁 b马口铁 c高速合金钢 d碳素纤维"); } //试题2 public void testQuestion2(){ System.out.println("杨过、程英、陆无双铲除了情花,造成【】a 使这种植物不再害人 b使一种珍惜物种灭绝 c破坏了生物圈的生态平衡 d造成该地区沙漠化"); } }
public class TestPaperA extends TestPaper{ //试题1 public void testQuestion1(){ super.testQuestion1(); System.out.println("答案: b"); } //试题2 public void testQuestion2(){ super.testQuestion2(); System.out.println("答案: a"); } }
public class TestPaperB extends TestPaper{ //试题1 public void testQuestion1(){ super.testQuestion1(); System.out.println("答案: d"); } //试题2 public void testQuestion2(){ super.testQuestion2(); System.out.println("答案: b"); } }
public class Test { public static void main(String[] args) { System.out.println("-----------------------"); TestPaperA ta = new TestPaperA(); ta.testQuestion1(); ta.testQuestion2(); TestPaperB tb = new TestPaperB(); tb.testQuestion1(); tb.testQuestion2(); } }
这里我们把题目都放到了TestPaper父类中,这样就不会出现题目抄错的情况。但我们发现,子类中还是有过多的重复代码。需要改进一下,模板方法登场了,当我们要完成某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。
第三版:
public abstract class ITestPaper { //试题1 public void testQuestion1(){ System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是【】a 球磨铸铁 b马口铁 c高速合金钢 d碳素纤维"); System.out.println("答案:" + answer1()); } //试题2 public void testQuestion2(){ System.out.println("杨过、程英、陆无双铲除了情花,造成【】a 使这种植物不再害人 b使一种珍惜物种灭绝 c破坏了生物圈的生态平衡 d造成该地区沙漠化"); System.out.println("答案:" + answer2()); } protected abstract String answer1(); protected abstract String answer2(); }
public class TestPaperA1 extends ITestPaper{ @Override protected String answer1() { // TODO Auto-generated method stub return "a"; } @Override protected String answer2() { // TODO Auto-generated method stub return "b"; } }
public class TestPaperB1 extends ITestPaper{ @Override protected String answer1() { // TODO Auto-generated method stub return "c"; } @Override protected String answer2() { // TODO Auto-generated method stub return "d"; } }
public class Test { public static void main(String[] args) { System.out.println("-----------------------"); ITestPaper ta1 = new TestPaperA1(); ta1.testQuestion1(); ta1.testQuestion2(); ITestPaper tb1 = new TestPaperB1(); tb1.testQuestion1(); tb1.testQuestion2(); } }
这样,每一份题目我们只要填写选择题的答案即可,这是每个人的唯一的不同。
模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式是通过把不变的行为搬移到超类,去除子类中的重复代码来体现它的优势,