模板设计模式 您所在的位置:网站首页 模板设计的步骤 模板设计模式

模板设计模式

#模板设计模式| 来源: 网络整理| 查看: 265

模板设计模式—基于抽象类的,核心是封装算法 模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供具体实现模板(模板方法)模式(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(); } }

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有