模板方法模式:定义一个操作中的算法的骨架,而将一些步骤迟到到子类中。
要点:
1.模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。
2.模板方法提供了一个很好的代码复用平台,通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。
3.模板方法是代码复用的一项基本的技术,在类库中尤其重要。
它遵循“抽象类应当拥有尽可能多的行为,应当拥有尽可能少的数据”的重构原则。
适用性:
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
3.控制子类扩展。模板方法只在特定点调用Hook操作,这样就只允许在这些点进行扩展。
/** * 抽象模板类,定义并实现了一个模板方法,定义了一个算法的骨架。 * 模板方法一般是一个具体的方法,给出一个顶级逻辑的骨架,而逻辑的组成步骤 * 在相应的抽象操作中,推迟到子类实现. */ public abstract class AbstractClass { // 一些抽象行为,放到子类去实现 public abstract void primitiveOperation1(); public abstract void primitiveOperation2(); //模板方法,给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作, 它们都推迟到子类实现。 public void templateMethod(){ this.primitiveOperation1(); this.primitiveOperation2(); } }
/** * 实现父类所定义的一个或多个抽象方法。 * */ public class ConcreteClassA extends AbstractClass { @Override public void primitiveOperation1() { System.out.println("具体类A方法1实现"); } @Override public void primitiveOperation2() { System.out.println("具体类A方法2实现"); } }
/** * 实现父类所定义的一个或多个抽象方法。 * */ public class ConcreteClassB extends AbstractClass { @Override public void primitiveOperation1() { System.out.println("具体类B方法1实现"); } @Override public void primitiveOperation2() { System.out.println("具体类B方法2实现"); } }
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub AbstractClass abstractClass = null; abstractClass = new ConcreteClassA(); abstractClass.templateMethod(); abstractClass = new ConcreteClassB(); abstractClass.templateMethod(); } }
模板方法实例:(学生考试)
/** * 考题试卷类 * */ public abstract class TestPaper { //考题1 public void testQuestion1(){ System.out.println("杨过得到,然后给了郭靖,后来。。。请问。。" + "【】a.球1 b.球2 c.球3 d.球4 "); System.out.println("答案:"+this.answer1()); } //考题2 public void testQuestion2(){ System.out.println("杨过,程英,陆无双铲除了情花,造成【】" + "a.灭绝1 b.灭绝2 c.灭绝3 d.灭绝4 "); System.out.println("答案:"+this.answer2()); } //考题3 public void testQuestion3(){ System.out.println("如果你是丈夫,会给他们开什么药【】" + "a.药1 b.药2 c.药3 d.药4 "); System.out.println("答案:"+this.answer3()); } // 给继承的子类来实现,因为每个人的答案是不同的 protected abstract String answer1(); protected abstract String answer2(); protected abstract String answer3(); }
/** * 学生甲抄的试卷 * */ public class TestPaperA extends TestPaper { @Override public String answer1() { return "a"; } @Override public String answer2() { return "b"; } @Override public String answer3() { return "c"; } }
/** * 学生乙抄的试卷 * */ public class TestPaperB extends TestPaper { @Override public String answer1() { return "b"; } @Override public String answer2() { return "d"; } @Override public String answer3() { return "a"; } }
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("学生甲抄的试卷:========="); TestPaper testPaperA = new TestPaperA(); testPaperA.testQuestion1(); testPaperA.testQuestion2(); testPaperA.testQuestion3(); System.out.println("学生乙抄的试卷:=========="); TestPaper testPaperB = new TestPaperB(); testPaperB.testQuestion1(); testPaperB.testQuestion2(); testPaperB.testQuestion3(); } }
输出结果如下:
学生甲抄的试卷:========= 杨过得到,然后给了郭靖,后来。。。请问。。【】a.球1 b.球2 c.球3 d.球4 答案:a 杨过,程英,陆无双铲除了情花,造成【】a.灭绝1 b.灭绝2 c.灭绝3 d.灭绝4 答案:b 如果你是丈夫,会给他们开什么药【】a.药1 b.药2 c.药3 d.药4 答案:c 学生乙抄的试卷:========== 杨过得到,然后给了郭靖,后来。。。请问。。【】a.球1 b.球2 c.球3 d.球4 答案:b 杨过,程英,陆无双铲除了情花,造成【】a.灭绝1 b.灭绝2 c.灭绝3 d.灭绝4 答案:d 如果你是丈夫,会给他们开什么药【】a.药1 b.药2 c.药3 d.药4 答案:a