当我们遇到的业务逻辑具有大致相同的方式的时候,我们也许就该将这个业务逻辑抽象出来,采用模板方法,来进行封装我们的代码,提高代码的重用性,以及可维护性。下面是我的一个复习用的案例:
第一步:我们需要一个抽象出来的父类,其要实现的就是我们这个业务逻辑的大致的雏形,需要注意的是里面有一个”钩子“方法,用于定制子类的特有的活动方式:
package Template;
/**
* 抽象基类,为其所有的子类提供以一个算法框架
*
* @author Tiger
*
*/
public abstract class AbstractSubClass {
/*
* 模板方法,封装了所有子类索要共同进行遵循的算法框架
*/
public final void prepareTemplateMethod() {// final修饰,避免子类对其重写
// 步骤1
Step1();
// 步骤2
Step2();
// 步骤3
Step3();
if(isCustom()){//钩子概念,当为真的时候就会调用步骤四方法
// 步骤4
Step4();
}
}
/**
* 包访问权限,只有在同一个包内的类才能够被访问
* @return
*/
protected boolean isCustom() {
// TODO Auto-generated method stub
return false;
}
// 由于接下来的子类中对该方法的操作不一样,所以声明为抽象的方法,以便于“多态”的实现
protected abstract void Step4();
/**
* 基本方法,步骤3
*/
private void Step3() {
System.out.println("步骤3");
}
// 由于接下来的子类中对该方法的操作不一样,所以声明为抽象的方法,以便于“多态”的实现
protected abstract void Step2();
/**
* 基本方法,步骤一
*/
private void Step1() {
System.out.println("步骤一");
}
}
然后我们可以创建第一个子类:
package Template;
/**
* 这是第一个抽象类的子类,里面有只适合这一个类的方法的实现
* @author Administrator
*
*/
public class SubClassOne extends AbstractSubClass {
@Override
protected void Step4() {
// TODO Auto-generated method stub
System.out.println("第一个子类的专属的步骤4");
}
@Override
protected void Step2() {
// TODO Auto-generated method stub
System.out.println("第一个子类的专属的步骤2");
}
@Override
protected boolean isCustom() {
// TODO Auto-generated method stub
return true;//此处是在子类中,"钩住"了父类的方法,实现了自定义的方式
}
}
然后是第二个子类,其实和第一个类大致相同,仅仅是某些方法内的逻辑代码不一致而已。
package Template;
/**
* 这是第一个抽象类的子类,里面有只适合这一个类的方法的实现
* @author Administrator
*
*/
public class SubClassTwo extends AbstractSubClass {
@Override
protected void Step4() {
// TODO Auto-generated method stub
System.out.println("第二个子类的专属的步骤4");
}
@Override
protected void Step2() {
// TODO Auto-generated method stub
System.out.println("第二个子类的专属的步骤2");
}
@Override
protected boolean isCustom() {
// TODO Auto-generated method stub
return false;//此处是在子类中,"钩住"了父类的方法,实现了自定义的方式
}
}
好了,接下来就是测试要用的类了:
package Template;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("第一个子类开始了");
AbstractSubClass sub1=new SubClassOne();//其实这就是多态的实现
sub1.prepareTemplateMethod();
System.out.println("第一个子类的实现过程结束了");
System.out.println("-------------------------------------");
System.out.println("第二个子类开始了");
AbstractSubClass sub2=new SubClassTwo();//同样的,其实这就是多态的实现
sub2.prepareTemplateMethod();
System.out.println("第二个子类的实现过程结束了");
System.out.println("-------------------------------------");
}
}
下面就是我们的程序的运行结果:
第一个子类开始了
步骤一
第一个子类的专属的步骤2
步骤3
第一个子类的专属的步骤4
第一个子类的实现过程结束了
-------------------------------------
第二个子类开始了
步骤一
第二个子类的专属的步骤2
步骤3
第二个子类的实现过程结束了
-------------------------------------
我们可以看出,使用了钩子方法的类就会调用相关的方法,结果我们就得到了不一样的运行结果。其实这就是多态的另一种展现形式。
总结:模板方法优点很多,但是也由于是继承的关系,所以会导致子类继承的时候有些问题。大致的实现步骤是,先抽象出来一个大致实现了所有方法的父类,然后对相关的方法进行抽象处理,让子类对其进行逻辑代码的实现,这样大大的增加了程序的灵活性。然而最经典上的事我们的钩子方法,其使得用户可以自定义的真正实现,使得我们的代码更加精致。
好了,java模式中的模板模式,大致就是这样了。