基本介绍

模板方法模式 是在一个固定步骤的方法骨架中,将某些步骤延迟到子类实现,以便重新定义该方法中的某些特定步骤。

模板方法模式属于行为型模式,较为简单。

 

假设我们开了一家早餐店,每天早上一大早我们就要研磨豆浆,研磨豆浆的步骤都是特定的,只是原材料不同,它们都要进行 选材 -》 添加配料 -》 浸泡 -》 放到豆浆机研磨

  • 添加不同的配料可以制作不同口味的豆浆
  • 选材、浸泡以及豆浆机研磨这几个步骤对于每种口味的豆浆而言都是相同的

模板方法模式-LMLPHP

 

模板方法模式

根据上面的场景,我们显然发现在所有步骤里,唯独添加配料这个步骤是不同的,那么我们就把这个步骤交给子类实现

 

豆浆类

/**
 * 抽象类表示豆浆
 */
public abstract class SoyaMilk {

    /**
     * 模板方法, make, 模板方法可以制作成final,不让子类去覆盖
     */
    final void make(){
        select();
        if(isAddCondiments()){
            addCondiments();
        }
        soak();
        beat();
    }

    /**
     * 选材料
     */
    private void select(){
        System.out.println("第一步:选择上好的新鲜黄豆");
    }

    /**
     * 添加不同的配料,抽象方法,让子类去实现具体的逻辑
     */
    abstract void addCondiments();

    /**
     * 钩子方法 是否添加配料
     */
    abstract boolean isAddCondiments();

    /**
     * 浸泡
     */
    private void soak(){
        System.out.println("第三步:黄豆和配料开始浸泡, 需要3小时");
    }

    private void beat(){
        System.out.println("第四步:用豆浆机打磨黄豆和配料");
    }


}

 

红豆豆浆

/**
 * 红豆豆浆
 */
public class ReadBeanMilk extends SoyaMilk {

    @Override
    void addCondiments() {
        System.out.println("加入上好的红豆");
    }

    @Override
    boolean isAddCondiments() {
        return true;
    }

}

 

花生豆浆

/**
 * 花生豆浆
 */
public class PeanutSoyaMilk extends  SoyaMilk{

    @Override
    void addCondiments() {
        System.out.println("加入上好的花生");
    }

    @Override
    boolean isAddCondiments() {
        return true;
    }

}

 

纯豆浆(纯豆浆不添加任何配料),需要利用钩子方法

/**
 * 纯豆浆
 */
public class PureMilk extends SoyaMilk{

    void addCondiments(){};

    @Override
    boolean isAddCondiments() {
        return false;
    }
}

 

注: 在模板方法模式的父类,定义一个方法不做任何事,子类可以视情况要不要覆盖它,称该方法“为钩子”

 

模板方法模式-LMLPHP

07-23 19:05