定义:
Define the skeleton of algorithm in an operation , deferring some steps to subclass.
Template method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.
在操作中定义一个算法的骨架,骨架将一些实现步骤延迟到子类中。
模板方法让子类定义一些骨架的步骤,却不会改变骨架定义的步骤结构
其他:子类继承了父类的方法,通过从父类继承过来的方法,反过来调用子类的自身实现方法(曲线理解为父类调用子类的方法)。在很多框架中,提示你继承一个抽象类,然后执行一个类似 execute() 的方法,就完成了功能扩展,就是应用了模板模式
关键:定义模板方法的类是一个抽象类,该类定义了一系列的step抽象方法,并定义了一个调用这些step 的实现方法。
行为由父类控制,子类实现自身的一些业务实现
类图:
一 定义模板
package dmode.templete;
/**
* 类描述:中国式教育模板类
* 在抽象类中指定模板,让子类实现抽象类中的其他方法,这是抽象类的一个好处
* @version 1.0 CreateDate: 2015-2-12
*
* @updateDate
* @updatePerson
* @declare
*/
public abstract class EducationTemp {
/**
* 方法描述:小学教育
*/
public abstract void primaryEdu();
/**
* 方法描述:初中教育
*/
public abstract void middleEdu();
/**
* 方法描述:高中教育
*/
public abstract void seniorEdu();
/**
* 方法描述:大学教育
*/
public abstract void universityEdu();
/**
* 方法描述:是否接受大学教育
* 此方法为钩子方法,定义一个抽象方法,让子类实现;根据子类的返回值,来决定模板方法中的操作逻辑
* @return
*/
public abstract boolean ifAcceptUnivEdu();
/**
* 方法描述:教育模板
*/
public void edu(){
this.primaryEdu();
this.middleEdu();
this.seniorEdu();
if(this.ifAcceptUnivEdu()){
this.universityEdu();
}
}
}
二:定义 实现模板的子类
package dmode.templete; /** * 类描述: 学生A * @version 1.0 CreateDate: 2015-2-12 * * @updateDate * @updatePerson * @declare */ public class StudentA extends EducationTemp{ /** * 默认A 接受大学教育 */ private boolean acceptUnivEdu = true; /** *@see dmode.templete.EducationTemp#primaryEdu() */ @Override public void primaryEdu() { System.out.println("A 进行小学教育"); } /** *@see dmode.templete.EducationTemp#middleEdu() */ @Override public void middleEdu() { System.out.println("A 进行中学教育"); } /** *@see dmode.templete.EducationTemp#seniorEdu() */ @Override public void seniorEdu() { System.out.println("A 进行高中教育"); } /** *@see dmode.templete.EducationTemp#universityEdu() */ @Override public void universityEdu() { System.out.println("A 进行大学教育"); } /** *@see dmode.templete.EducationTemp#ifAcceptUnivEdu() *学生A 接不接受大学教育由他自己决定 */ @Override public boolean ifAcceptUnivEdu() { return this.acceptUnivEdu; } /** * 方法描述:具体上不上大学,A在实际情况中自己决定 * @param acceptUnivEduFlag */ public void setAcceptUnivEdu(boolean acceptUnivEduFlag){ this.acceptUnivEdu = acceptUnivEduFlag; } }
package dmode.templete;
/**
* 类描述:学生B
* @version 1.0 CreateDate: 2015-2-12
*
* @updateDate
* @updatePerson
* @declare
*/
public class StudentB extends EducationTemp{
/**
*@see dmode.templete.EducationTemp#primaryEdu()
*/
@Override
public void primaryEdu() {
System.out.println("B 进行小学教育");
}
/**
*@see dmode.templete.EducationTemp#middleEdu()
*/
@Override
public void middleEdu() {
System.out.println("B 进行中学教育");
}
/**
*@see dmode.templete.EducationTemp#seniorEdu()
*/
@Override
public void seniorEdu() {
System.out.println("B 进行高中教育");
}
/**
*@see dmode.templete.EducationTemp#universityEdu()
*/
@Override
public void universityEdu() {
System.out.println("B 进行大学教育");
}
/**
*@see dmode.templete.EducationTemp#ifAcceptUnivEdu()
*学生B 接受大学教育
*/
@Override
public boolean ifAcceptUnivEdu() {
return true;
}
}
三 调用场景
package dmode.templete; /** * 类描述: 入口 * @version 1.0 CreateDate: 2015-2-12 * * @updateDate * @updatePerson * @declare */ public class Acce { public static void main(String[] args) { //对于有自身特定行为的类,用子类自身来接收 StudentA a = new StudentA(); a.setAcceptUnivEdu(false); //大众的学生由抽象类来接收就可以 EducationTemp b = new StudentB(); a.edu(); System.out.println("=================="); b.edu(); } }
输出:
A 进行小学教育
A 进行中学教育
A 进行高中教育
==================
B 进行小学教育
B 进行中学教育
B 进行高中教育
B 进行大学教育