5.JAVA模板方法模式总结

这篇文章介绍一种笔者认为最最最简单的设计模式,模板方法模式。

0.抛出问题

在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体架构同时实现。如何在确定稳定操作结构的前提下,来灵活应对各个子步骤的变化或者晚期实现需求?

1.具体场景

举个栗子,现在我们用机器自动生产汉堡,通常来说汉堡的结构是确定的,两层面包中间夹上食材,不过有时候中间的食材可能是生菜,猪肉、牛肉、鸡肉、半鸡半虾(说的我好饿= =)。所以我们就可以定一个抽象类的汉堡,为一个汉堡模板,假设我们的汉堡结构为面包+生菜+肉+面包。代码如下

public abstract class Hamburger {
    public final void getHamburger(){
        topBread();
        lettuce();
        meat();
        bottomBread();
    }

    protected void topBread(){
        System.out.println("上面的面包");
    }

    protected void lettuce(){
        System.out.println("中间的生菜");
    }
    protected abstract void meat();

    protected void bottomBread(){
        System.out.println("底部的面包");
    }
}

给getHamburger加上final的原因是防止子类错误的复写,如果复写为一个汉堡上层是生菜,中间是两片面包,底层是肉饼,就不符合逻辑了...

现在我们要做一个深海鳕鱼堡

public class CodFishBurger extends Hamburger {
    @Override
    protected void meat() {
        System.out.println("深海鳕鱼");
    }
}

测试类

public class Test {
    public static void main(String[] args)
    {
        Hamburger codFishBurger=new CodFishBurger();
        codFishBurger.getHamburger();
    }
}
\\测试结果
上面的面包
中间的生菜
深海鳕鱼
底部的面包

Process finished with exit code 0

这时候如果我们需要一个新奥尔良汉堡或者一个田园脆鸡堡,我们只需要写出相应的类去继承抽象汉堡类。

在这里顺便告诉大家一个冷知识,肯德基或者麦当劳是可以根据你的需求去做汉堡的,在点汉堡的时候我们可以告诉点餐员不加生菜等需求。

在模板方法中,我们需要一个勾子,去根据需求决定是否去调用某个的方法。
修改代码如下

public abstract class Hamburger {
    private boolean lettuceHook = true;//默认是有生菜的

    protected void setLettuceHook(boolean lettuceHook) {//根据需求决定是否加生菜
        this.lettuceHook = lettuceHook;
    }

    public final void getHamburger() {
        topBread();
        if (lettuceHook)
            lettuce();
        meat();
        bottomBread();
    }

    protected void topBread() {
        System.out.println("上面的面包");
    }

    protected void lettuce() {
        System.out.println("中间的生菜");
    }

    protected abstract void meat();

    protected void bottomBread() {
        System.out.println("底部的面包");
    }
}

测试类

public class Test {
    public static void main(String[] args)
    {
        System.out.println("第一个汉堡:");
        Hamburger codFishBurger=new CodFishBurger();
        codFishBurger.getHamburger();
        System.out.println("第二个汉堡:");
        Hamburger codFishBurger2=new CodFishBurger();
        codFishBurger2.setLettuceHook(false);
        codFishBurger2.getHamburger();
    }
}
//测试结果
第一个汉堡:
上面的面包
中间的生菜
深海鳕鱼
底部的面包
第二个汉堡:
上面的面包
深海鳕鱼
底部的面包

2.要点总结

优点:灵活地实现具体的算法,满足用户灵活多变的需求
缺点:算法骨架需要改变时需要修改抽象类

模板方法模式是一种非常基础性的设计模式,在面向对象中有着大量的应用(如java的HttpServlet)。它用最简洁的机制(抽象函数的多态性)实现为很多应用框架提供了灵活的扩展点,是代码复用方面的基本实现结构。除了可以灵活应对子步骤变化外,“不要调用我,让我来调用你”的反向控制结构是模板方法的典型应用。

你可能感兴趣的:(5.JAVA模板方法模式总结)