模板设计模式

模板设计模式—基于抽象类的,核心是封装算法

  • 模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供具体实现
  • 模板(模板方法)模式(Servlet、AQS)
    • 在一个方法中定义一个算法的骨架,并将一些具体步骤延迟到子类中实现。
    • 模板模式使得子类可以在不改变算法结构的基础上,重新具体定义算法中的某些步骤

讲模板设计模式之前,我们用代码来实现咖啡和茶制作的类:

class Coffee {    
    /*   
     * 咖啡冲泡法(算法)     
    */    
    void prepareRecipe() {        
        boilWater();        
        brewCoffeeGrings();        
        pourInCup();        
        addSugarAndMilk();    
    }       
    public void boilWater() {        
        System.out.println("将水煮沸");    
    } 
    public void brewCoffeeGrings() {        
        System.out.println("冲泡咖啡");    
    }  
    public void pourInCup() {        
        System.out.println("把咖啡倒进杯子中");    
    }
    public void addSugarAndMilk() {        
        System.out.println("加糖和牛奶");    
    } 
}

class Tea {    
    /*   
     * 冲泡茶法(算法)     
    */    
    void prepareRecipe() {        
        boilWater();        
        steepTeaBag();        
        pourInCup();        
        addLemon();    
    }       
    public void boilWater() {        
        System.out.println("将水煮沸");    
    } 
    public void steepTeaBag() {        
        System.out.println("浸泡茶叶");    
    }  
    public void pourInCup() {        
        System.out.println("把茶倒进杯子中");    
    }
    public void addLemon() {        
        System.out.println("加柠檬");    
    } 
}
class Test {
    public static void main(String[] agrs) {
        Coffee coffee = new Coffee();
        Tea tea = new Tea();
        coffee.prepareRecipe();
        tea.prepareRecipe();
    }
}

在这里插入图片描述

我们在这两个类中发现了重复代码,因此我们需要重新理一下我们的设计。

  • 既然茶和咖啡是如此的相似,因此我们应该将共同的部分抽取出来,放进一个基类中。
  • 从冲泡法入手。观察咖啡和茶的冲泡法我们会发现,两种冲泡法都采用了相同的算法:
    • 将水煮沸
    • 用热水泡饮料
    • 把饮料倒进杯子
    • 在饮料内加入适当的调料

实际上,浸泡(steep)和冲泡(brew)差异并不大。因此我们给它一个新的方法名称brew(),这样我们无论冲泡的是何种饮 料都可以使用这个方法。同样的,加糖、牛奶还是柠檬也很相似,都是在饮料中加入其它调料,因此我们也给它一 个通用名称addCondiments()。

/** 
 * 咖啡因饮料是一个抽象类 
**/ 
abstract class CaffeineBeverage {    
    /**
     * 现在用同一个prepareRecipe()方法处理茶和咖啡。     
     * 声明为final的原因是我们不希望子类覆盖这个方法!     
    **/    
    final void prepareRecipe() {        
        boilWater();        
        brew();        
        pourInCup();        
        addCondiments();   
    }
     /**     
      * 咖啡和茶处理这些方法不同,因此这两个方法必须被声明为抽象,留给子类实现     
     **/    
    abstract void brew();    
    abstract void addCondiments();

    void boilWater() {        
         System.out.println("将水煮沸");    
    }
    void pourInCup() {        
         System.out.println("把饮料倒进杯子中");    
    } 
}
 
class Coffee extends CaffeineBeverage {     
    public void brew() {        
        System.out.println("冲泡咖啡");    
    }  
    public void addCondiments() {        
        System.out.println("加糖和牛奶");    
    } 
}

class Tea extends CaffeineBeverage {    
    public void brew() {        
        System.out.println("浸泡茶叶");    
    }  
    public void addCondiments() {        
        System.out.println("加柠檬");    
    } 
}
class Test {
    public static void main(String[] agrs) {
        CaffeineBeverage coffee = new Coffee();
        CaffeineBeverage tea = new Tea();
        coffee.prepareRecipe();
        tea.prepareRecipe();
    }
}

模板方法定义了一个算法的步骤,并允许子类为一个或者多个步骤提供具体实现

在模板设计模式下还有一种钩子用法

钩子方法是一类"默认不做事的方法" ,子类可以视情况决定要不要覆盖它们。
比如说,顾客点杯咖啡时,可以选择加不加牛奶或者糖!!!

import java.util.Scanner;

/** 
 * 咖啡因饮料是一个抽象类 
**/ 
abstract class CaffeineBeverage {    
    /**
     * 现在用同一个prepareRecipe()方法处理茶和咖啡。     
     * 声明为final的原因是我们不希望子类覆盖这个方法!     
    **/    
    final void prepareRecipe() {        
        boilWater();        
        brew();        
        pourInCup();   
        if(customerWantsCondiments())     
            addCondiments();   
    }
     /**     
      * 咖啡和茶处理这些方法不同,因此这两个方法必须被声明为抽象,留给子类实现     
     **/    
    abstract void brew();    
    abstract void addCondiments();

    void boilWater() {        
         System.out.println("将水煮沸");    
    }
    void pourInCup() {        
         System.out.println("把饮料倒进杯子中");    
    } 
    boolean customerWantsCondiments() {
        return true;
    }
}
 
class Coffee extends CaffeineBeverage {     
    public void brew() {        
        System.out.println("冲泡咖啡");    
    }  
    public void addCondiments() {        
        System.out.println("加糖和牛奶");    
    } 

     /**  
      * 子类覆写了钩子函数,实现自定义功能   
     **/ 
    boolean customerWantsCondiments() {
        String result = getUserInput();
        if(result.equals("y"))
            return true;
        else
            return false;
    }    
    private String getUserInput() {
        System.out.println("您想要在咖啡中加入牛奶或糖吗(y/n)?");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();
        return str;
    }
}

class Tea extends CaffeineBeverage {    
    public void brew() {        
        System.out.println("浸泡茶叶");    
    }  
    public void addCondiments() {        
        System.out.println("加柠檬");    
    } 
}
class Test {
    public static void main(String[] agrs) {
        CaffeineBeverage coffee = new Coffee();
        CaffeineBeverage tea = new Tea();
        coffee.prepareRecipe();
        tea.prepareRecipe();
    }
}

在这里插入图片描述
在这里插入图片描述

  • 79
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
Java中的模板设计模式是一种行为型设计模式,它允许我们定义一个算法的骨架,但允许子类为其中的一些步骤提供具体的实现。 模板设计模式由两个主要组件组成: 1. 抽象类(Abstract Class):它定义了一个模板方法,该方法提供了算法的骨架。它可以包含一个或多个抽象方法,这些方法由子类来实现。 2. 具体类(Concrete Class):它是抽象类的子类,负责实现抽象方法。 以下是一个示例代码来说明模板设计模式的用法: ```java public abstract class AbstractClass { // 模板方法 public final void templateMethod() { // 步骤一 stepOne(); // 步骤二 stepTwo(); // 步骤三 stepThree(); } // 抽象方法,由子类实现 protected abstract void stepOne(); protected abstract void stepTwo(); // 钩子方法,子类可以选择性地覆盖 protected void stepThree() { // 默认实现 } } public class ConcreteClass extends AbstractClass { @Override protected void stepOne() { // 具体实现步骤一 } @Override protected void stepTwo() { // 具体实现步骤二 } } ``` 在上面的示例中,`AbstractClass` 是抽象类,它定义了一个名为 `templateMethod()` 的模板方法,并声明了三个抽象方法 `stepOne()`、`stepTwo()` 和 `stepThree()`。`ConcreteClass` 是具体类,它继承了 `AbstractClass` 并实现了抽象方法。 通过使用模板设计模式,我们可以在抽象类中定义算法的骨架,而具体的实现可以由子类来完成。这种设计模式使得代码重用和扩展变得更加容易。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值