设计模式——模板方法模式

本文通过饮料机的例子,深入浅出地介绍了模板方法模式的概念、应用及优势。模板方法模式通过将固定步骤抽取到父类,减少子类重复代码,提高开发效率与系统可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式——模板方法模式

小时候每次考试的时候,都希望考卷都是写好的,每个人发一张,然后大家写上自己名字交卷子就可以了23333。

1.情景举例

公司又要制造机器了,我们的麻烦也就又来了。

这两天,来了个新活儿,有个餐厅的一角放几个自助饮料机。经过调查之后,发现员工们普遍喜欢咖啡,橙汁,茶水。于是公司接了这个活。设计团队首先定义了一个所有饮料机的父类,以便统一管理他们。

public abstract class DrinkMachine {
    
    private String drinkName;

    public DrinkMachine(String drinkName) {
        this.drinkName = drinkName;
    }
    
    public abstract void getDrink();
}

每个具体的饮料需要实现getDrink()方法即可。然后小组长让每个组员实现一个具体的硬料机。

public class CoffeeMachine extends DrinkMachine {

    public CoffeeMachine() {
        super("Coffee");
    }

    @Override
    public void getDrink() {
        System.out.println("加入水");
        System.out.println("加入咖啡豆");
        System.out.println("研磨");
        System.out.println("开启水阀");
        System.out.println(drinkName +"流出");
        System.out.println("关闭水阀");
    }
}
public class JuiceMachine extends DrinkMachine {

    public JuiceMachine(String drinkName) {
        super("OrangeJuice");
    }

    @Override
    public void getDrink() {
        System.out.println("加入水");
        System.out.println("加入橘子果肉");
        System.out.println("榨汁混合");
        System.out.println("开启水阀");
        System.out.println(drinkName +"流出");
        System.out.println("关闭水阀");
    }
}
public class TeaMachine extends DrinkMachine {

    public TeaMachine(String drinkName) {
        super("Tea");
    }

    @Override
    public void getDrink() {
        System.out.println("加入水");
        System.out.println("加入茶叶");
        System.out.println("冲泡");
        System.out.println("开启水阀");
        System.out.println(drinkName +"流出");
        System.out.println("关闭水阀");
    }
}

三个组员忙了一晚上,终于完成了各自的任务(其实实际任务并不是打印流程这么简单的)。第二天他们在一起讨论的时候的发现三个人晚上干的活有50%是重复的,于是他们对组长安排的任务产生了怀疑。在经过学习之后,他们准备通过模板方法模式重构代码,然后给组长一个惊喜。

2.使用模板方法模式

首先组员A偷偷把组长写好的父类进行了修改。

public abstract class DrinkMachine {

    private String drinkName;

    public DrinkMachine(String drinkName) {
        this.drinkName = drinkName;
    }

    public void getDrink() {
        enterWater();
        makeDrink();
        setWaterValue();
    };

    public void enterWater() {
        System.out.println("加入水");
    };

    public abstract void makeDrink();

    public void setWaterValue() {
        System.out.println("开启水阀");
        System.out.println(drinkName +"流出");
        System.out.println("关闭水阀");
    }
}

整个制作饮料的过程被分成了三步,其中的两步都是固定的,因此在父类就已经实现了。剩下的一步是和饮料的类型有关的,因此要根据子类的不同有不同的实现,所以把makeDrink()方法设置为抽象方法,等待子类实现。父类还更改了getDrink()方法,在该方法中调用其他三步方法获得饮料,把该方法作为用户使用的接口。

其他两个组员则是对3个子类进行了改造,因为公共的部分已经由父类实现了,现在他们只需要实现每个子类中特有的部分就可以了。

public class CoffeeMachine extends DrinkMachine {

    public CoffeeMachine() {
        super("Coffee");
    }
    
    @Override
    public void makeDrink() {
        System.out.println("加入咖啡豆");
        System.out.println("研磨");
    }
}
public class JuiceMachine extends DrinkMachine {

    public JuiceMachine() {
        super("OrangeJuice");
    }

    @Override
    public void makeDrink() {
        System.out.println("加入橘子果肉");
        System.out.println("榨汁混合");
    }
}
public class TeaMachine extends DrinkMachine {

    public TeaMachine() {
        super("Tea");
    }

    @Override
    public void makeDrink() {
        System.out.println("加入茶叶");
        System.out.println("冲泡");
    }
}

大功告成之后他们发现每个子类中的重复代码大大的减少了,而且就算以后要制作新的饮料机,继承饮料机父类就能得到公共的功能(加入水的操作和开启、关闭水阀门的操作),然后只需要编写这个饮料机特定的操作代码即可。

他们高兴坏了,准备立刻测试一下。

public class MainTest {

    public static void main(String[] args) {
        ArrayList<DrinkMachine> list = new ArrayList<>(3);
        list.add(new CoffeeMachine());
        list.add(new JuiceMachine());
        list.add(new TeaMachine());

        for (DrinkMachine drinkMachine : list) {
            drinkMachine.getDrink();
            System.out.println();
        }
    }
}

和预期的一样完美,他们已经迫不及待的给组长进行一份炫耀了。

3.模板方法模式小结

模板方法定义了一个模板。在这个模板中完成了公共代码的实现,留出等待子类生成的空缺的部分,子类只需要根据自己的特性补全空缺的部分即可。

模板方法模式大大减少了继承体系中的重复代码,而且减小了整体出错率(没办法,有些人就是抄也能抄错)。

在实际开发中,如果发现一个继承体系的每个子类的整套功能在宏观上具有一致性,并且有着部分相同的动作,那么就可以尝试使用模板方法模式去重新构建这个继承结构。可以提高开发的效率,还能增加系统扩展性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值