简单纪要:5分钟,教你学会模板模式!

模板模式又叫模版方法模式(Template Method Pattern),是指定义一个算法的骨架,允许不同的子类进行实现,子类可以为一个或多个步骤来实现。模板模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤,属于行为型设计模式。

模版模式适用于以下场景:

(1)一次性实现算法的不变部分,并将可变的行为留给子类来实现。

(2)各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复。
我们平时常用的ReentrantLock底层框架AQS(AbstractQueuedSynchronizer)就是基于模板方法模式来实现的,具体可参考过往文章-穿越门:https://www.cnblogs.com/Rnan/p/11962259.html

 下面我们以一个炒菜的样例演示一下模板方法模式的使用;

制作菜肴的步骤可以分为:洗菜,切菜,放油,炒菜,出锅

第一步:定义抽象类Cook

/**
 * @author Rnan
 */
abstract class Cook {
    public abstract void washVegetables(String name);

    public abstract void cutVegetables(String name);

    public void drainTheOil(String name){
        System.out.println("drainTheOil + " + name + "开始放油了");
    }

    public void makeSeasoning(String name){
        System.out.println("makeSeasoning + " + name + "开始放调料了");
    }

   //钩子方法
public boolean seasoning(){ return false; } public String outOfThePot(String name){ return "成品菜:" + name + "出锅了"; } public String stirFry(String name){ return "stirFry + " + name + "翻炒"; } public final void make(String name){ // 洗菜 this.washVegetables(name); // 切菜 this.cutVegetables(name); // 放油 this.drainTheOil(name); // 要不要放调料 if(seasoning()){ this.makeSeasoning(name); } this.stirFry(name); // 出锅 System.out.println(this.outOfThePot(name)); } }

抽象类定义出完整的流程,和模板中不变的部分,将可变的部分开放给子类去实现,例如:washVegetables() 和 cutVegetables(),子类可以根据自己的具体操作是实现,父母定义完整的流程,不允许重写,就像make()方法;

第二步:定义具体的子类

class ScrambledEggsWithTomatoes extends Cook{
    // 要不要放调料
    boolean isSeasoningFlag = false;

    @Override
    public void washVegetables(String name) {
        System.out.println("washVegetables + 西红柿清洗完毕");
    }

    @Override
    public void cutVegetables(String name) {
        System.out.println("cutVegetables + 西红柿切丁");
    }

    public void setSeasoning(Boolean flag){
        this.isSeasoningFlag = flag;
    }

    @Override
    public boolean seasoning(){
        return this.isSeasoningFlag;
    }

    @Override
    public String outOfThePot(String name){
        return "outOfThePot + " + name +"大菜出锅";
    }
}

第三步:定义场景类:

public static void main(String[] args) {
        System.out.println("开始制作西红柿炒鸡蛋");
        String next = new Scanner(System.in).next();
        ScrambledEggsWithTomatoes scrambledEggsWithTomatoes = new ScrambledEggsWithTomatoes();
        if("true".equalsIgnoreCase(next)){
            scrambledEggsWithTomatoes.setSeasoning(true);
        }
        scrambledEggsWithTomatoes.make("西红柿炒蛋");
    }

 

 

 通过定义钩子方法,可以让子类控制父类的一些方法要不要执行,就想红框中的,要不要放调料这个操作,子类就可以通过修改参数来控制;

模板方法实现非常简单,就是java的继承机制,我们定义的cook类就叫做抽象模板,一般为了防止恶意操作,抽象模板都被加上final关键字,防止被重写覆盖;

模板方法就是如此,大家可以动手操作下,有问题可以评论留言,下次见~

posted @ 2022-09-12 14:31  爱吃螃蟹的牧羊人  阅读(119)  评论(0编辑  收藏  举报