开发之路(设计模式九:模板方法模式)

让一切变得更简单抽象化

深入封装算法块,这便是设计模式当中的一种模式:模板方法模式。
我们先来看看下面两个茶和咖啡配方
图片描述

也许我们可以很快用Java代码实现出来,但我觉得做之前先分析分析,咖啡和茶的冲泡方式中第(1)步骤是完全一样的,我认为这样肯定会出现重复代码,写代码尽量不写重复代码,而第(2)(3)(4)步骤大体相似,

我们将两者步骤合起来看看
图片描述

实现代码如下

咖啡因抽象类

package 改进之后;

/**
 * 咖啡因饮料(抽象类) 带钩子方法 模板方法
 * 
 * @author Joy
 * 
 */
public abstract class CaffeineBeverageWithHook {
    // 制作流程
    public void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        /*
         * 加上一个条件,具体有customerWantsCondiments()方法决定,当用户“想要”调料时,才调用addCondiments()方法
         */
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

    /**
     * 因为咖啡和茶都有这两个方法,但只是具体实现不同 所以这两个方法必须声明为抽象,具体实现交由子类
     */
    // 冲泡的方法抽取出来
    public abstract void brew();

    // 加调料方法抽取出来
    public abstract void addCondiments();

    public void boilWater() {
        System.out.println("煮沸水");
    }

    public void pourInCup() {
        System.out.println("将饮料倒入杯子中");
    }

    /**
     * 定义一个方法(通常为空),这个方法只会返回true 这就是一个钩子方法 子类需根据需求是否覆盖这个方法
     * 
     * @return
     */
    // 添加一个新(“钩子”)方法,判断顾客是否需要添加调料
    public boolean customerWantsCondiments() {
        return true;
    }
}

咖啡类

package 改进之后;

import java.util.Scanner;

public class CoffeeWithHook extends CaffeineBeverageWithHook {

    @Override
    public void brew() {
        System.out.println("把沸水冲泡咖啡");
    }

    @Override
    public void addCondiments() {
        System.out.println("加糖加牛奶");
    }

    // 对此作出判断
    public boolean customerWantsCondiments() {
        String answer = getUserInput();
        if (answer.equals("y")) {
            return true;
        }
        System.out.println("咖啡不加调料");
        return false;
    }

    // 询问顾客是否需要加糖加奶
    private String getUserInput() {
        String answer = null;
        Scanner input = new Scanner(System.in);
        System.out.println("请问你是否需要在咖啡里加糖加奶呢?(y/n)");
        answer = input.next();
        if (answer.equals("y")) {
            return answer;
        } else if (answer.equals("n")) {
            return answer;
        } else {
            return "error";
        }
    }
}

茶类

package 改进之后;

import java.util.Scanner;

public class TeaWithHook extends CaffeineBeverageWithHook {

    @Override
    public void brew() {
        System.out.println("把沸水浸泡茶叶");
    }

    @Override
    public void addCondiments() {
        System.out.println("加柠檬");
    }

    @Override
    public boolean customerWantsCondiments() {
        String answer = getUserInput();
        if (answer.equals("y")) {
            return true;
        }
        System.out.println("茶不加调料");
        return false;
    }

    // 询问顾客是否需要加糖加奶
    private String getUserInput() {
        String answer = null;
        Scanner input = new Scanner(System.in);
        System.out.println("请问你是否需要在茶里加柠檬呢?(y/n)");
        answer = input.next();
        if (answer.equals("y")) {
            return answer;
        } else if (answer.equals("n")) {
            return answer;
        } else {
            return "error";
        }
    }
}

测试类

package 改进之后;

public class TestMain {
    public static void main(String[] args) {
        CoffeeWithHook coffeeHook = new CoffeeWithHook();
        TeaWithHook teaHook = new TeaWithHook();
        System.out.println("========制作咖啡");
        coffeeHook.prepareRecipe();

        System.out.println("\n========制作茶");
        teaHook.prepareRecipe();
    }
}

效果图
图片描述
图片描述

而所谓“钩子”方法其实是根据不同情况而做出不同响应结果的一种判断方法,这其我就实现一个最简单的钩子方法,根据y/n的输入得出用户是否要加入调料。

定义模板方法模式:在一个方法中定义一个算法的框架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤。

注:模板就是一个方法,这个方法将算法定义成一组步骤,其中的任何步骤都可以是抽象的,由子类去实现。

感谢你看到这里,模板方法模式到这里就结束了,本人文笔随便,若有不足或错误之处望给予指点,90度弯腰~~~很快我会发布下一个设计模式的内容,生命不息,编程不止!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值