首页 > 其他分享 >模板方法模式

模板方法模式

时间:2023-08-06 17:05:34浏览次数:39  
标签:子类 void System 模式 println 方法 模板

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

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

要点

  • 模板方法定义了算法的步骤,把这些步骤的实现延迟到了子类。
  • 模板方法模式为我们提供了一种代码复用的重要技巧。
  • 模板方法的抽象类可以定义具体方法,抽象方法和钩子。
  • 抽象方法由子类实现。
  • 钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它。
  • 为了防止子类改变模板方法中的算法,可以将模板方法声明为final。
  • 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。

介绍

**意图:**定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

**主要解决:**一些方法通用,却在每一个子类都重新写了这一方法。

**何时使用:**有一些通用的方法。

**如何解决:**将这些通用算法抽象出来。

**关键代码:**在抽象类实现,其他步骤在子类实现。

应用实例: 1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。 2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。 3、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。

优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。

**缺点:**每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。

使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。

**注意事项:**为防止恶意操作,一般模板方法都加上 final 关键词。

实现

package HeadFirstDesignMode.templatemethod;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * 描述:模板方法模式
 */
public class TemplateMethodPattern {
    public static void main(String[] args) {
        TeaHook myTeaHook = new TeaHook();
        CoffeeHook coffeeHook = new CoffeeHook();

        myTeaHook.prepareRecipe();
        System.out.println("开始喝茶...");
        System.out.println();

        coffeeHook.prepareRecipe();
        System.out.println("开始喝咖啡...");
    }

}

abstract class CaffeineBeverageWithHook {
    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;
    }

    protected String getUserInput() {
        String answer = null;
        System.out.println("要加调料吗?(y/n)");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
            answer = in.readLine();
        } catch (IOException e) {
            System.err.println("请检查你的输入!!");
        }
        return answer == null ? "n" : answer;

    }
}

class TeaHook extends CaffeineBeverageWithHook {

    @Override
    void brew() {
        System.out.println("开始泡茶");
    }

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

    @Override
    boolean customerWantsCondiments() {
        String answer = getUserInput();
        return "y".equalsIgnoreCase(answer);
    }
}

class CoffeeHook extends CaffeineBeverageWithHook {

    @Override
    void brew() {
        System.out.println("开始磨咖啡");
    }

    @Override
    void addCondiments() {
        System.out.println("添加糖和牛奶");
    }
    @Override
    boolean customerWantsCondiments() {
        String answer = getUserInput();
        return "y".equalsIgnoreCase(answer);
    }
}

标签:子类,void,System,模式,println,方法,模板
From: https://blog.51cto.com/u_11906056/6985094

相关文章

  • 常见的电商模式 B2B、B2B、C2B、C2C、O2O
    1电商模式市面上有5种常见的电商模式B2B、B2B、C2B、C2C、O2O1.1B2B模式B2B(BusinesstoBusiness),是指商家和商家建立的商业关系,如阿里,1.2B2C模式B2C(BusinesstoConsumer)就是我们经常看到的供应商直接把商品买个用户,即“商对客”模式,也就是我们呢说的商业零售......
  • C# 类型的扩展方法定义
    C#类型的扩展方法定义扩展方法就是类型的静态方法属性,比如:.ToString()其实是可以自定义类型的方法的,按如下操作:1、定义静态类​namespaceExtenClass​{​publicstaticclassObjectExtention{}​}  2、定义静态方法,方法的第一个参数必须是thisTYPEPARATYP......
  • 数组,条件,循环,重要函数,超级全局变量,魔术方法
    目录数组,条件,循环,实战重要函数超级全局变量魔术方法数组,条件,循环,实战数组在PHP中,array()函数用于创建数组:$cars=array("Volvo","BMW","Toyota");在PHP中,有三种类型的数组:数值数组-带有数字ID键的数组关联数组-带有指定的键的数组,每个键关联一个值......
  • 在macOS上启动AutoCAD软件时显示“许可检出超时“的解决方法
    Macos上使用AutoCAD时,弹出茶品许可超市,AutoCAD即将关闭的情况怎么办呢,到底是哪里出现了问题呢?不妨试试下面这种方法。AutoCAD204forMac最新安装Issue:在macOS上启动Autodesk软件产品时,显示类似以下内容的消息,且程序必须关闭:产品许可证-超时许可检出超时。您要执行什么......
  • replace方法解决全部替换的问题
    replace函数一次只能替换一个目标字符串。当需要替换多个相同目标时,可以配合while循环替换所有字符串1.替换一个目标字符串constprase="一个中国北方的中国人在做中国结"constuseReplace=prase.replace("中国","")console.log(useReplace); 2.替换多个目标字符串......
  • 策略模式
    IfyoucanNOTexplainitsimply,youdoNOTunderstanditwellenough**介绍:**定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户**主要解决:**在有多种算法相似的情况下,使用if…else所带来的复杂和难以维护。**何时使用:**一个系......
  • 观察者模式
    **介绍:**定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖都会收到通知并自动更新。**主要解决:**一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。**何时使用:**一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得......
  • 装饰者模式
    装饰者模式**装饰者模式:**动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。*设计原则:*类应该对扩展开放,对修改关闭继承属于扩展形式之一,但不见得是达到弹性设计的最佳方式。在我们的设计中,应该允许行为可以被扩展,而无须修改现有的代码。组合和......
  • 工厂方法模式
    工厂方法模式**工厂方法模式:**定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。设计原则:依赖倒置原则:要依赖抽象,不要依赖具体类。下面的指导方针,能避免在OO设计原则中违反依赖倒置原则:变量不可以持有具体的类的引用。不要让......
  • 【JavaScript09】模板字符串(Template Strings)
    前言JavaScript在ES6新增了模板字符串(TemplateStrings)语法,其作用是可以在字符串中换行,以及将变量和表达式插入字符串。模板字符串模板字面量使用反引号(``)而不是单引号('')或双引号("")来定义字符串示例:letuser="xwl";letage=20;letx=`myname......