模板方法

《大话设计模式》第10读书笔记,介绍模板方法

Posted by GrayWind on October 31, 2018

模板方法模式,定义一个操作系统中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

其实就是相当于把一些公共的方法提出到模板类里面,然后把一些不同的部分放到子类中进行具体实现。就像从一个模板衍生出的不同图案。

template

AbstractClass是抽象类,也就是抽象模板,定义并实现了一个具体的模板方法,其中调用了抽象操作由子类来完成。模板方法中也可以调用一些具体方法。

public abstract class AbstractClass {
	public abstract void primitiveOperation1();
	public abstract void primitiveOperation2();
	
	public void TemplateMethod() {
		primitiveOperation1();
		primitiveOperation2();
	}
}

ConcreteClass,实现父类所定义的一个或多个抽象方法。每一个AbstractClass都可以有任意多个ConcreteClass与之对应,而每个ConcreteClass都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各部相同

public class ConcreateClassA extends AbstractClass{

	@Override
	public void primitiveOperation1() {
		System.out.println("具体类A方法1实现");
	}

	@Override
	public void primitiveOperation2() {
		System.out.println("具体类A方法2实现");
	}

}

public class ConcreateClassB extends AbstractClass{

	@Override
	public void primitiveOperation1() {
		System.out.println("具体类B方法1实现");
	}

	@Override
	public void primitiveOperation2() {
		System.out.println("具体类B方法2实现");
	}

}

测试类

	public static void main(String[] args) {
		AbstractClass c;
		c = new ConcreateClassA();
		c.TemplateMethod();
		//具体类A方法1实现
		//具体类A方法2实现
		
		c = new ConcreateClassB();
		c.TemplateMethod();
		//具体类B方法1实现
		//具体类B方法2实现
	}

模板方法模式通过把不变的行为搬到超类,去除子类中的重复代码来体现它的优势,提供了一个很好的复用平台。当不变和可变的实现混合在一起时,我们可以把不变的实现放到模板抽象类中,把可变的实现留在具体实现类方法中。

以下面的考试卷为例,将考卷作为模板类,学生答题作为具体实现类。可以看到,在模板中,题干是固定的,而答案需要由学生来实现。

public abstract class TestPaper {
	public void testQuestion1() {
		System.out.println("1*5=" + answer1());
	}
	
	public void testQuestion2() {
		System.out.println("2+5=" + answer2());
	}
	
	public void testQuestion3() {
		System.out.println("9-3=" + answer3());
	}
	
	protected abstract String answer1();
	protected abstract String answer2();
	protected abstract String answer3();
}

学生的回答如下

public class TestPaperA extends TestPaper {

	@Override
	protected String answer1() {
		return "5";
	}

	@Override
	protected String answer2() {
		return "7";
	}

	@Override
	protected String answer3() {
		return "6";
	}

}

public class TestPaperB extends TestPaper {

	@Override
	protected String answer1() {
		return "2";
	}

	@Override
	protected String answer2() {
		return "4";
	}

	@Override
	protected String answer3() {
		return "6";
	}

}

测试代码

	public static void main(String[] args) {
		System.out.println("学生甲的试卷");
		TestPaper studentA = new TestPaperA();
		studentA.testQuestion1();//1*5=5
		studentA.testQuestion2();//2+5=7
		studentA.testQuestion3();//9-3=6
		
		System.out.println("学生乙的试卷");
		TestPaper studentB = new TestPaperA();
		studentB.testQuestion1();//1*5=5
		studentB.testQuestion2();//2+5=7
		studentB.testQuestion3();//9-3=6
	}