作者:云都小生
概述
模板方法模式的内容,其实从一开始接触抽象类的知识时就有所涉及了。抽象类中可以定义具体的方法,也可以定义一些抽象方法。
继承自该抽象类后,就会自动拥有具体方法,并且必须实现抽象类中的抽象方法。
想一想,其实抽象类可以让我们实现一些“模板”,在这些模板中,我们可以先把所有子类都一样的方法写成具体方法,这样子类继承就能直接拥有。
我们可以定义一些抽象方法,由于每个子类的实现都有可能不同,所以我们让每个子类自己去实现。
案例
模板方法模式,解决的是一种特殊的场景,举个例子。在某款游戏中,玩家可以领取到许多不同的任务,这个过程中的顺序是固定的——领取任务、完成任务、提交任务。只是有一个部分不一样,那就是完成任务的过程,这个过程是不确定的。
在这种场景下,我们就能这样去设计。
public abstract class AbstractFather {
public void Sequence()
{
GetTask();
DoTask();
RefTask();
}
public void GetTask()
{
System.out.println("您领取了任务");
}
abstract void DoTask();
public void RefTask()
{
System.out.println("您提交了任务");
}
}
public class ConcreteChild extends AbstractFather{
void DoTask()
{
System.out.println("更改了项目需求");
}
}
public class Test {
public static void main(String[] args) {
ConcreteChild con = new ConcreteChild();
con.Sequence();
}
}
//测试结果
//您领取了任务
//更改了项目需求
//您提交了任务
通过这个案例中,我们介绍模板方法模式的两种角色。
角色介绍
在模板方法模式中通常有两种角色,一种是抽象类,一种是子类。
抽象类:抽象类中定义了一个基本的算法操作(算法框架),就像上面的案例一样,接任务 -> 完成任务 -> 提交任务,这就算是一个基本的算法操作。
并且,在抽象类中,定义了一些具体的方法,也定义了一些抽象的方法。
具体子类:可以调用、覆盖、实现子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。
此外,在抽象类中有时候还可以有一个“钩子”方法,这个钩子方法可以用来控制步骤是否执行。
我们来看个栗子。
public abstract class AbstractFather {
public void Sequence()
{
GetTask();
if(Checkhook())
{
DoTask();
}
RefTask();
}
private boolean Checkhook()
{
return true;
}
public void GetTask()
{
System.out.println("您领取了任务");
}
abstract void DoTask();
public void RefTask()
{
System.out.println("您提交了任务");
}
}
在这个抽象类中我们增加了一个钩子方法Checkhook(),这个方法默认返回true,也就是默认要执行DoTask()方法。
我们的子类继承之后,如果不想执行这个步骤,就可以覆盖掉这个Checkhook()方法。
private boolean Checkhook()
{
return false;
}
这样就不会执行了。
总结
模板方法模式是一种代码复用技术,通过模板方法模式,我们能控制算法的执行流程。如果有需要,还可以对原来的业务方法进行重写。
重要的是,通过这个模式,我们可以轻易的自定义抽象方法中的业务,不必用大量if判断来决定执行哪种业务方法。
2018/4/10 13:40:54 @Author:云都小生