模板方法模式

来源:互联网 发布:网络用语py什么意思 编辑:程序博客网 时间:2024/06/05 05:31

模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

这个模板是用来创建一个算法的模板。模板就是一个方法。这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类负责实现。
这里写图片描述
模板方法被声明为final,避免子类改变这个算法的顺序。在这个模板方法中,算法内的每个步骤都被一个方法代表了,某些方法(通用部分)有这个超类处理;而另一些方法则有子类处理。需要由子类提供的方法,必须在超类中声明为抽象。

对模板方法进行挂钩
钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩(子类可以控制算法的步骤)。

当子类必须提供算法中某个方法或步骤的实现时,就使用抽象方法。如果算法的这个部分是可选的,就用钩子。如果是钩子,子类可以选择实现这个钩子,但并不强制这么做。子类可以视情况决定要不要覆盖它们。

钩子可以让子类实现算法中可选的部分,或者在钩子对于子类的实现并不重要的时候,子类可以对此钩子置之不理。钩子能够让子类能够有机会对模板方法中的某些即将发生的(或刚刚发生的)步骤作出反应。

需求实例:定义一个泡茶或咖啡的模板方法(流程算法)。
1、模板方法

//定义抽象类public  abstract class CaffeineBeverageWithHook {    //定义模板方法    void prepareRecipe(){        //把水煮沸        boilWater();        //泡茶或咖啡        brew();        //倒入杯中        pourIncup();        //钩子方法        if(customerWantsCondiments()){            //加入调料            addCondiments();        }    }    //这两个抽象方法由子类实现    abstract void brew();    abstract void addCondiments();    //通用的方法    void boilWater(){        System.out.println("Boiling water");    }    void pourIncup(){        System.out.println("pour into cup");    }    //钩子方法:默认不做事的方法。这是一个具体的方法,子类视情况是否覆盖它    boolean customerWantsCondiments(){        return true;    }}

2、子类实现抽象方法,覆盖钩子方法:

public class CaffeeHook extends CaffeineBeverageWithHook {    //实现抽象方法    public void brew(){        System.out.println(" coffee brew");    }    public void addCondiments(){        System.out.println("add condiments");    }    //覆盖钩子方法    public boolean customerWantsCondiments(){        String answer=getUserInput();        if(answer.startsWith("y")){            return true;        }else {            return false;        }    }    private String getUserInput(){        return "yes";    }}