理解模板模式

模板模式是一种行为型设计模式,它允许在抽象类中定义算法框架,子类可重定义算法的特定步骤。通过煎牛排和煎鸡蛋的例子,展示了如何使用模板模式减少重复代码,同时保持算法结构不变。子类只需关注特定步骤的实现,如煎鸡蛋仅需覆盖准备食材的方法,而煎牛排则还需覆盖是否需要红酒的钩子方法。模板模式在不修改算法结构的情况下,实现了算法的多样化。
摘要由CSDN通过智能技术生成

        在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。换句话说:抽象父类定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

        在上例子之前,先说一下:模板模式中的方法分为两大类:模版方法和基本方法,而基本方法又分为:抽象方法,具体方法,钩子方法。

用煎牛排和煎鸡蛋来举例说明:

1.煎牛排:

public class FriedSteak {

    /**
    * @Description: 煎牛排方法
    * @Author: yyf
    * @Date: 2021/7/21
    */
    void cook(){
        prepareBeef();
        fried();
        eat();
        prepareWine();
    }

    private void prepareBeef() {
        System.out.println("准备牛肉");
    }

    private void fried() {
        System.out.println("油煎");
    }

    private void eat() {
        System.out.println("开吃");
    }

    private void prepareWine() {
        System.out.println("再配瓶红酒~");
    }

    public static void main(String[] args) {
        FriedSteak FriedSteak = new FriedSteak();
        FriedSteak.cook();
    }

}

执行结果: 

2.煎鸡蛋:

public class FriedEggs {

    /**
    * @Description: 煎鸡蛋方法
    * @Author: yyf
    * @Date: 2021/7/21
    */
    void cook(){
        prepareEggs();
        fried();
        eat();
    }

    private void prepareEggs() {
        System.out.println("准备鸡蛋");
    }

    private void fried() {
        System.out.println("油煎");
    }

    private void eat() {
        System.out.println("开吃");
    }

    public static void main(String[] args) {
        FriedEggs friedEggs = new FriedEggs();
        friedEggs.cook();
    }
}

执行结果: 

对比煎牛排和煎鸡蛋,我们发现其中准备食材的方法是类似的,油煎和开吃的方法是固定不变的,准备红酒是煎牛排特有的(现实也可以煎鸡蛋配红酒~)。为了减少代码的冗余,这个时候就可以使用模版模式来定义好煎制食物的骨架方法,看代码:

建一个煎制食物的抽象父类:

/** 
* @Description: 煎制食物抽象类
* @Author: yyf
* @Date: 2021/7/21 
*/
public abstract class FriedFood {
    //cook方法就是前文说的模版方法,也是煎制食品的骨架,final修饰
    final void cook(){
        prepareFood();
        fried();
        eat();
        if(needWine()){
            System.out.println("再配瓶红酒~");
        }
    }

    //准备食材作为基本方法里的抽象方法,供子类实现
    protected abstract void prepareFood();

    //油煎和开吃是基本方法里的具体方法,不可覆盖
    private void fried() {
        System.out.println("油煎");
    }
    private void eat() {
        System.out.println("开吃");
    }

    //是否需要红酒是基本方法里的钩子方法,返回一个空实现,子类可以选择是否覆盖
    boolean needWine() {
        return false;
    }

    public static void main(String[] args) {
        FriedFood friedEggs = new FriedEggsNew();
        friedEggs.cook();
        System.out.println("-------------------");
        FriedFood friedSteak = new FriedSteakNew();
        friedSteak.cook();
    }
}

子类煎鸡蛋继承煎制食物父类并覆盖父类的prepareFood()抽象方法

public class FriedEggsNew extends FriedFood{

    //这里必须覆盖父类FriedFood的准备食材抽象方法
    @Override
    protected void prepareFood() {
        System.out.println("准备鸡蛋");
    }

}

子类煎牛排继承煎制食物父类并覆盖父类的prepareFood()抽象方法,并且覆盖父类的needWine()钩子方法

public class FriedSteakNew extends FriedFood{

    //这里必须覆盖父类FriedFood的准备食材抽象方法
    @Override
    protected void prepareFood() {
        System.out.println("准备牛肉");
    }

    //煎牛排时想配红酒喝,所以选择覆盖父类的needWine方法
    @Override
    boolean needWine(){
        return true;
    }
}

来看执行结果: 

总结:

        抽象父类定义一个操作中的算法的骨架,子类在不改变一个算法的结构即可重定义该算法的某些特定步骤。这种设计模式就是模板模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值