模板模式

定义:
定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构即可重定义该算法的某些特定步骤。通俗点的理解就是 :完成一件事情,有固定的数个步骤,但是每个步骤根据对象的不同,而实现细节不同;就可以在父类中定义一个完成该事情的总方法,按照完成事件需要的步骤去调用其每个步骤的实现方法。每个步骤的具体实现,由子类完成。

模板模式、策略模式、工厂方法三者之间的区别:

1 模板模式:子类决定如何实现算法中的步骤;

2 策略模式: 封装可互换的行为,然后使用委托决定要采用哪一个行为。

3 工厂方法:由子类来决定实例化哪个类。

类关系:

抽象父类(AbstractClass):实现了模板方法,定义了算法的骨架。

具体类(ConcreteClass):实现抽象类中的抽象方法,即不同的对象的具体实现细节。

实例:

定义算法骨架抽象类:
复制代码
public abstract class CaffeineBeverageWithHook {
    // 定义算法骨架
    void prepareRecipe(){
        boilWater();
        brew();
        pourInCup();
        if(customersWantsCondiments()){
            addCondiments();
        }
    }

    abstract void brew();

    abstract void addCondiments();

    void boilWater(){
        System.out.println("boiling water");
    }

    void pourInCup(){
        System.out.println("pouring into cup");
    }

    // 钩子,作为条件控制,影响算法的流程
    boolean customersWantsCondiments(){
        return true;
    }
}
复制代码

 

定义特定实现类1:

复制代码
public class CoffeeWithHook extends CaffeineBeverageWithHook{
    @Override
    void brew() {
        System.out.println("Dripping Coffee through filter");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Sugar and Milk");
    }

    boolean customersWantsCondiments() {
        String answer = getUserInput();
        if(answer.toLowerCase().startsWith("y")){
            return true;
        }else{
            return false;
        }
    }

    private String getUserInput(){
        String answer = null;
        System.out.println("Would you like milk and sugar with your coffee (y/n)?");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try{
            answer = in.readLine();
        }catch (Exception e){
            System.out.println("read answer failed");
        }
        if(answer == null){
            return "no";
        }
        return answer;
    }
}
复制代码

 

定义特定实现类2:

复制代码
public class TeaWithoutHook extends CaffeineBeverageWithHook {
    @Override
    void brew() {
        System.out.println("Steeping the tea");
    }

    @Override
    void addCondiments() {
        System.out.println("Adding Lemon");
    }
}
复制代码

 

测试代码:

复制代码
public class BeverageTest {
    public static void main(String[] args){
        TeaWithoutHook teaWithoutHook = new TeaWithoutHook();
        CoffeeWithHook coffeeWithHook = new CoffeeWithHook();

        System.out.println("Making tea\n");
        teaWithoutHook.prepareRecipe();

        System.out.println("Making Coffee\n");
        coffeeWithHook.prepareRecipe();
    }
}
复制代码

 

测试结果:

Making tea
boiling water
Steeping the tea
pouring into cup
Adding Lemon

Making Coffee
boiling water
Dripping Coffee through filter
pouring into cup
Would you like milk and sugar with your coffee (y/n)?
y
Adding Sugar and Milk

posted @   小兵要进步  阅读(54)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)

侧边栏
点击右上角即可分享
微信分享提示