设计模式之模板方法模式

1. 模板方法模式(Template Method)

        模板方法模式是带有模板功能的模式,组成模板的抽象方法被定义在父类中,父类只负责管理子类可以调用哪些方法,而抽象方法的具体实习由子类完成,在子类中决定具体的处理流程。也就是说,在不同的子类中实现不同的具体处理,但无论子类中具体如何实现,处理的流程都会按照父类中定义的那样进行

        像这样在父类中定义处理流程的框架,在子类中实现具体处理的模式就称为Template Method模式

1.1. 模式架构

  • 抽象类(AbstractClass):抽象模板类负责给出算法的轮廓和骨架,它由一个模板方法和若干个基本方法构成。模板方法定义了整体的骨架,按某种顺序执行调用其包含的基本方法,基本方法的具体流程由具体子类实现
  • 具体类(ConcreteClass):负责实现抽象类中定义的抽象方法,这些方法会在抽象类中被调用

1.2. 示例代码实现

        场景:平常做饭时大致流程是有统一的模板的,具体的做饭流程一致,区别在于不同的菜有不同的处理工序,该业务就很适合使用模板方法模式。

抽象类(AbstractClass):

抽象模板类CookDiner

public abstract class CookDiner {
    public abstract void WashFoods();//交给子类去实现抽象方法WashFoods
    public abstract void CutFoods();//交给子类去实现抽象方法CutFoods
    public final void Cook(){//本抽象类中实现的Cook方法,确定执行骨架和流程
        WashFoods();
        CutFoods();
        //做饭
        System.out.println("开始做饭");
    }
}

具体类(ConcreteClass):

具体类Vegetables

public class Vegetables extends CookDiner {//Vegetables类是CookDiner类的子类
    private String vegetName;

    public Vegetables(String vegetName) {
        this.vegetName = vegetName;
    }

    @Override
    public void WashFoods() {//重写WashFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始洗:" + vegetName);
    }

    @Override
    public void CutFoods() {//重写CutFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始切:" + vegetName);
    }
}

具体类Meat

public class Meat extends CookDiner {//Meat类是CookDiner类的子类
    private String meatName;

    public Meat(String meatName) {
        this.meatName = meatName;
    }

    @Override
    public void WashFoods() {//重写WashFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始洗:" + meatName);
    }

    @Override
    public void CutFoods() {//重写CutFoods方法,该方法会在Cook方法中被调用
        System.out.println("开始切:" + meatName);
    }
}

Main类:

public class Client {
    public static void main(String[] args) {
        //生成一个持有"黄瓜"的Vegetables类的实例
        CookDiner cookVeget = new Vegetables("黄瓜");
        //生成一个持有"牛肉"的Meat类的实例
        CookDiner cookMeat = new Meat("牛肉");

        //cookVeget、cookMeat都是CookDiner类的子类
        cookVeget.Cook();//可以调用继承的Cook方法
        cookMeat.Cook();//实际的程序行为取决于cookVeget类和cookMeat类的具体实现
    }
}

执行结果:

开始洗:黄瓜

开始切:黄瓜

开始做饭

开始洗:牛肉

开始切:牛肉

开始做饭

        在以上示例代码中,抽象模板类CookDiner定义了程序行为的框架和流程,父类通过Cook方法来按照流程处理方法,具体的方法由其子类Vegetables、Meat来实现。

        与策略模式不同的是,模板方法模式会改变部分程序行为,而策略模式是用于替换整个算法

1.3. 优缺点

优点

  • 代码复用:公共代码抽取到模板方法中,避免重复实现。
  • 扩展性:子类可以根据需要重写特定步骤,不影响算法整体结构。
  • 结构清晰:算法框架清晰可见,易于理解和维护。

缺点

  • 固化框架:有时过度使用模板方法可能会导致框架过于固定,不利于灵活应对变化。
  • 复杂度增加:可能会增加系统的复杂度,特别是当算法步骤较多、逻辑复杂时。

适用场景:

  • 多个子类有共同的方法,并且逻辑基本相同:通过模板方法将这些共同的方法提取到父类中,避免重复代码。
  • 需要控制子类的扩展:模板方法定义了算法的框架,子类只需实现特定的细节,而框架本身不变。
上一篇:云端荣耀:在iCloud中记录您的个人成就与荣誉


下一篇:科研绘图系列:R语言STAMP图(STAMP Plot)-介绍