跳转至

模板方法模式

图片的样式

模板方法它适用于一整个业务的逻辑大体是固定不变的,好多地方都在用,但是某一天突然有一个需求, 和这个逻辑几乎一样,但是又有一些细节不同,那为了避免代码重复,保证以后也可以新增代码时不大面积改动代码, 就可以考虑模板方法模式。它可以使代码复用,可以控制扩展,易于维护,但是会限制子类的灵活性,还使得代码变复杂。

🏀代码样例

平时使用豆浆机时,我们的第一步都是选择新鲜的豆子,然后将豆子和配料开始浸泡3H,最后将豆子和配料放入豆浆机榨汁就行了。 但是放啥配料,放不放配料,都会改变具体步骤。

public abstract class SoyaMilk {
    /*
     * 模板方法:可以做成final,不让子类去覆盖
     */
    final void make() {
        select();
        if (customerWantCondiment()) {
            addCondiment();
        }
        soak();
        beat();
    }

    // 1️⃣选材料
    void select() {
        System.out.println("第一步:选择新鲜的豆子");
    }

    // 2️⃣第二步:添加不同的配料:抽象方法,由子类具体实现
    abstract void addCondiment();

    // 3️⃣浸泡
    void soak() {
        System.out.println("第三步:豆子和配料开始浸泡3H");
    }

    // 4️⃣榨汁
    void beat() {
        System.out.println("第四步:豆子和配料放入豆浆机榨汁");
    }

    // 钩子方法:决定是否需要添加配料
    boolean customerWantCondiment() {
        // 默认情况下是要加配料的, 那些需要配料的豆浆品种就不需要覆写
        return true;
    }
}

这时候大家的步骤都是一样的,如何体现个性呢?我们去实现一下这个类,一样的步骤就不重写了, addCondiment()是决定每个子类差异的方法,也可以有多个。

public class OriginalSoyaMilk extends SoyaMilk{
    @Override
    void addCondiment() {
        // 添加配料的方法 空实现 即可 原味豆浆不需要配料
    }

    /*
    * 原味豆浆不需要添加,记得要返回false
    */
    @Override
    boolean customerWantCondiment() {
        return false;
    }
}
public class PeanutSoyaMilk extends SoyaMilk {
    @Override
    void addCondiment() {
        System.out.println("第二步:加入上好的花生");
    }
}
public class ReadBeanSoyaMilk extends SoyaMilk{
    @Override
    void addCondiment() {
        System.out.println("第二步:加入上好的红豆");
    }
}
public class CoffeeSoyalMilk extends SoyaMilk{
    @Override
    void addCondiment() {
        System.out.println("第二步:加入上好的花生");
    }

    /*也可以改其他的模板步骤*/
    @Override
    void beat() {
        System.out.println("第四步:豆子和配料放入咖啡机做咖啡,举个例子🌰而已");
    }
}

其中模板类里面的钩子🪝方法可以看情况去除。

🐔使用方式

使用的时候,直接做豆浆就可以了,放到spring框架里面就是交给容器管理用到就注入

public class Client {
    public static void main(String[] args) {
        System.out.println("=======制作红豆豆浆=======");
        SoyaMilk redBeanSoyaMilk = new ReadBeanSoyaMilk();
        redBeanSoyaMilk.make();

        System.out.println("=======制作花生豆浆=======");
        SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
        peanutSoyaMilk.make();

        System.out.println("=======制作原味豆浆=======");
        OriginalSoyaMilk originalSoyaMilk = new OriginalSoyaMilk();
        originalSoyaMilk.make();

        System.out.println("=======制作咖啡豆浆=======");
        CoffeeSoyalMilk coffeeSoyalMilk = new CoffeeSoyalMilk();
        coffeeSoyalMilk.make();
    }
}
=======制作红豆豆浆=======
第一步:选择新鲜的豆子
第二步:加入上好的红豆
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入豆浆机榨汁
=======制作花生豆浆=======
第一步:选择新鲜的豆子
第二步:加入上好的花生
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入豆浆机榨汁
=======制作原味豆浆=======
第一步:选择新鲜的豆子
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入豆浆机榨汁
=======制作咖啡豆浆=======
第一步:选择新鲜的豆子
第二步:加入上好的花生
第三步:豆子和配料开始浸泡3H
第四步:豆子和配料放入咖啡机做咖啡,举个例子🌰而已