定义
定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
一般模板方法都加final关键字,不允许被复写。
首先定义一个抽象类,该类中的方法有两部分组成,基本方法和模板方法
public abstract class AbstractClass {
//基本方法
protected abstract void method1();
//基本方法
protected abstract void method2();
//模板方法
public void templateMethod() {
this.method1();
this.method2();
}
}
//实现类A
public class ClassA extends AbstractClass {
@Override
protected void method1() {
System.out.println("ClassA method1");
}
@Override
protected void method2() {
System.out.println("ClassA method2");
}
}
//实现类B
public class ClassB extends AbstractClass {
@Override
protected void method1() {
System.out.println("ClassB method1");
}
@Override
protected void method2() {
System.out.println("ClassB method2");
}
}
//客户端场景类
public class Client {
public static void main(String[] args) {
ClassA classA = new ClassA();
ClassB classB = new ClassB();
classA.templateMethod();
classB.templateMethod();
}
}
输出结果:
ClassA method1
ClassA method2
ClassB method1
ClassB method2
抽象模板中的方法尽量定义成protected类型,符合迪米特法则,实现类若非必要,尽量不要扩大父类中的访问权限。
优点
* 把不变的部分封装到父类中进行封装,而可变部分通过继承进行扩展。 * 抽取了公共部分,便于维护.。 * 基本方法由子类进行实现,子类可以自由扩展。行为由父类控制,子类进行实现。
缺点
一般来说,抽象类只负责声明最抽象、最一般的事务属性和方法,实现类完成具体的属性和方法。而在模板方法中,抽象类定义了部分抽象方法,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响。
使用场景
- 多个子类有公有的方法,并且逻辑基本相同时
- 重构代码时,把相同的代码进行抽取