深入浅出设计模式 - 模板方法模式

news2024/11/19 19:36:10

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)

💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

在这里插入图片描述

文章目录

  • 1、什么是模板方法模式
  • 2、模板方法模式的优缺点
  • 3、模板方法模式的应用场景
  • 4、模板方法模式的结构
  • 5、模板方法模式的代码案例

1、什么是模板方法模式

模板方法模式(Template Method Pattern)是一种行为设计模式,它定义了一个算法的框架,将一些步骤的具体实现延迟到子类中,使得子类可以改变算法的某些特定步骤,而不改变算法的结构。

模板方法模式的核心思想是:定义一个抽象类,其中包含一个模板方法,该方法中定义了算法的骨架,然后将一些步骤的实现交给子类去完成。子类可以重写这些步骤,从而改变算法的具体实现,但是算法的结构不会改变。

2、模板方法模式的优缺点

模板方法模式的优点包括:

  1. 将算法的骨架和具体实现分离,提高了代码的复用性和可维护性。

  2. 子类可以灵活地改变算法的某些步骤,从而实现不同的功能。

  3. 父类可以控制子类的执行顺序,保证算法的正确性。

模板方法模式的缺点包括:

  1. 父类和子类之间的耦合度较高,一旦父类的代码发生改变,可能会影响到子类的实现。

  2. 可能会导致类的数量增加,增加代码的复杂度。

3、模板方法模式的应用场景

模板方法模式适用于以下场景:

  1. 算法的整体步骤固定,但某些步骤的具体实现可以在子类中改变。

  2. 避免代码重复,将相同的代码抽象到父类中,子类只需要实现特定的代码即可。

  3. 父类需要控制子类的执行顺序,从而保证算法的正确性。

具体的应用场景有:

  1. 框架设计:框架中通常都会定义一些模板方法,子类通过实现特定的方法来完成框架的功能。

  2. 数据库访问:在访问数据库时,通常都需要进行连接、查询、关闭等操作,这些操作的顺序是固定的,但是具体的实现可以有所不同。

  3. 网络编程:在网络编程中,通常需要先建立连接、发送数据、接收数据等操作,这些操作的顺序是固定的,但是具体的实现可以有所不同。

  4. 面向对象设计:在面向对象设计中,通常会使用模板方法模式来实现一些通用的算法,如排序算法、搜索算法等。

  5. 游戏开发:在游戏开发中,通常需要实现一些通用的功能,如角色移动、攻击、防御等,这些功能的实现可以使用模板方法模式。

4、模板方法模式的结构

模板方法模式是一种行为设计模式,它定义了一个算法的骨架,并允许子类为一个或多个步骤提供实现。这种模式属于行为型模式。

模板方法模式的结构包括以下几个部分:

  1. 抽象类(AbstractClass):定义了算法的骨架,包含了若干个抽象方法,这些方法由子类实现。

  2. 具体类(ConcreteClass):实现了抽象类中定义的抽象方法,完成算法中的具体步骤。

  3. 钩子方法(Hook Method):在抽象类中定义的方法,子类可以选择性地覆盖它们,以改变算法的行为。

  4. 模板方法(Template Method):定义了算法的骨架,包含了一系列调用抽象方法和钩子方法的步骤,子类不能修改它的行为。

模板方法模式的核心思想是将算法的具体实现交给子类来完成,从而实现代码的复用和扩展。

5、模板方法模式的代码案例

package com.pany.camp.design.principle.template;

/**
 *
 * @description:  抽象类
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 22:42
 */
public abstract class CaffeineBeverage {
    
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();
        }
    }

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

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

    abstract void brew();

    abstract void addCondiments();

    boolean customerWantsCondiments() {
        return true;
    }
}
package com.pany.camp.design.principle.template;

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

/**
 * @description: 咖啡
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-27 22:42
 */
class Coffee extends CaffeineBeverage {
    void brew() {
        System.out.println("Dripping coffee through filter");
    }

    void addCondiments() {
        System.out.println("Adding sugar and milk");
    }

    boolean customerWantsCondiments() {
        String answer = getUserInput();
        return answer.toLowerCase().startsWith("y");
    }

    private String getUserInput() {
        String answer = null;
        System.out.print("Would you like sugar and milk with your coffee? (y/n) ");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
            answer = in.readLine();
        } catch (IOException e) {
            System.err.println("IO error trying to read your answer");
        }
        if (answer == null) {
            return "no";
        }
        return answer;
    }
}

package com.pany.camp.design.principle.template;

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

/**
 * @description: 茶
 * @copyright: @Copyright (c) 2022
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0
 * @createTime: 2023-06-27 22:43
 */
class Tea extends CaffeineBeverage {
    void brew() {
        System.out.println("Steeping the tea");
    }

    void addCondiments() {
        System.out.println("Adding lemon");
    }

    boolean customerWantsCondiments() {
        String answer = getUserInput();
        return answer.toLowerCase().startsWith("y");
    }

    private String getUserInput() {
        String answer = null;
        System.out.print("Would you like lemon with your tea? (y/n) ");
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        try {
            answer = in.readLine();
        } catch (IOException e) {
            System.err.println("IO error trying to read your answer");
        }
        if (answer == null) {
            return "no";
        }
        return answer;
    }
}
package com.pany.camp.design.principle.template;

/**
 *
 * @description:  客户端
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-27 22:43
 */
public class Client {
    public static void main(String[] args) {
        CaffeineBeverage coffee = new Coffee();
        CaffeineBeverage tea = new Tea();

        System.out.println("Making coffee...");
        coffee.prepareRecipe();

        System.out.println("\nMaking tea...");
        tea.prepareRecipe();
    }
}

CaffeineBeverage 是抽象类,定义了制作咖啡因饮料的模板方法 prepareRecipe() ,以及一些基本方法 boilWater() 和 pourInCup() 。 CaffeineBeverage 还定义了两个抽象方法 brew() 和 addCondiments() ,由子类实现。

Coffee 和 Tea 是具体类,实现了 brew() 和 addCondiments() 方法,以及 customerWantsCondiments() 钩子方法,可以根据客户的需求选择是否添加调料。

在 main 函数中,我们创建了 Coffee 和 Tea 对象,并调用它们的 prepareRecipe() 方法,输出了制作咖啡和茶的过程。

输出结果如下:

Making coffee...
Boiling water
Dripping coffee through filter
Pouring into cup
Would you like sugar and milk with your coffee? (y/n) y
Adding sugar and milk

Making tea...
Boiling water
Steeping the tea
Pouring into cup
Would you like lemon with your tea? (y/n) y
Adding lemon

Process finished with exit code 0

在这里插入图片描述

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/694280.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

修复u盘怎么做?4步快速完成u盘修复!

我的u盘用了好多年了,里面存了很多重要的照片。但最近不知道为什么我的u盘出现了各种问题,大家有什么修复u盘的好方法吗?或者我应该怎么样才能恢复我U盘里的重要数据呢? U盘作为一个便捷的存储工具,为我们保存数据提供…

SpringBoot整合SpringSecurity

一、概述 1.1 Spring Security和Shiro Spring Security 是Spring家族中的一个安全管理框架。 相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。 小项目有Shi…

ChatGPT:开放AI平台的最新进展和功能

第一章:引言 在过去的几年中,人工智能技术取得了长足的发展,其在各个领域的应用也日益广泛。而在AI技术中,自然语言处理(NLP)一直是备受关注的领域之一。ChatGPT作为OpenAI的开放AI平台上的一项重要技术&am…

【Duilib】通过xml文件布局界面

环境 VS版本:VS2013 概述 上一篇 【Duilib】入门 ,简单介绍了Duilib库的使用,这一篇测试一下通过xml布局界面。 步骤 1、创建工程 以 Win32\Win32项目 为模板创建TestByXml工程,步骤与上一篇基本一致。 2、创建MainWndFrame&a…

简单分享在微信上怎么实现分销功能

小程序分销开发怎么做?在如今的电商市场中,小程序分销成为了一种新兴的销售模式,通过分销模式,商家能够借助分销商的力量提高销售额,同时分销商也能不用投入大量资金和时间,就能在小程序上进行销售。那么&a…

FL Studio21中文版音频宿主软件下载教程

FL Studio是很适合新手上手的宿主软件,这得益于FL Studio独特的编曲逻辑。水果可以允许我们不使用音轨的思路来编曲。在FL Studio中我们创建一个pattern后,可以添加乐器或采样进去进行编写,编写完善后将Pattern拖进播放列表进行编排。不用区分…

高性能计算可以自学么?自学学完高性能计算能就业吗

随着超算互联网的认知越来越深,越来越多同学意识到高性能计算是未来有可能最好的就业方向之一。 高性能计算因其更偏底层、更不易被替代,因此广受广大大学生朋友和在职程序员的青睐。那么自学高性能计算可行吗?高性能计算可以自学吗&#xff…

2023年Java 毕业设计怎么选题,有哪些注意事项

个人简介:程序员徐师兄,7 年大厂程序员经历,擅长Java、微信小程序、Python、Android等,大家有这一块的问题可以一起交流! 各类成品java毕设 。javaweb,ssh,ssm,springboot等等项目框…

Microsoft Visual Studio × 出现错误,无去启动

Microsoft Visual Studio 出现错误,无去启动visual studio。 streamJsonRpc.RemotelnvocationException:cannot find service module info file ‘ldentitystorageservice.servicehub.service.json’ in ‘c:}ProgramFilesvicrosoft visual studio2022,Communitycommon7Servic…

【Java-15】反射知识总结

01_类的加载 类的加载过程类的加载时机 类的加载 当程序在运行后,第一次使用某个类的时候,会将此类的class文件读取到内存,并将此类的所有信息存储到一个Class对象中 说明:Class对象是指java.lang.Class类的对象,此类…

GaussDB WDR报告分析

标题 问题描述问题现象告警业务影响原因分析处理方法步骤 1步骤 2步骤 3步骤 4步骤 6步骤 7步骤 8步骤9步骤 10步骤 11步骤 12 问题描述 CPU使用率高。 问题现象 出现CPU使用率超过阈值,CPU使用率快速上涨或短时间持续较高水平等现象。 告警 CPU使用率告警。 …

去除小程序home按钮

前言:当我们未登录时,会跳转到登录页,但是这时候登录页左上角会有一个跳转到首页的按钮,但是,我们不希望出现这个回到首页的按钮 去除前: 去除后: 代码: onShow() {wx.hideHomeBut…

html5的drag属性实现拖放

70. html5的drag属性实现拖放 拖放&#xff08;Drag 和 Drop&#xff09;是很常见的特性。它指的是您抓取某物并拖入不同的位置。 拖放是 HTML5 标准的组成部分&#xff1a;任何元素都是可拖放的。 下面我们通过一个例子来实现拖放 <div id"drop" ondrop"…

快一起来看看好用的ai绘画以图生图教程有哪些吧

我朋友近期在研究ai绘画软件&#xff0c;想要用它创造出一些独特的艺术作品。所以他去查看了ai绘画软件排行榜&#xff0c;但是&#xff0c;里面有很多款不同类型的绘画软件&#xff0c;让人有点眼花缭乱。于是&#xff0c;他来问我ai绘画软件排行靠前的哪个好&#xff0c;我就…

Excel - Windows操作系统下的键盘快捷方式

注意&#xff1a; * 这些快捷方式指的是美式键盘布局。 其他键盘布局的键可能与美式键盘上的键不完全对应。 * 快捷方式中的加号 () 表示需要同时按多个键。 * 快捷方式中的逗号 (,) 表示需要按顺序按多个键。 * 如果经常使用的操作没有快捷键&#xff0c;则可以“录制宏”…

mybatis 模拟03

pom.xml: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0…

hexo stellar设置笔记页面

stellar主题的作者在其文档介绍了如何进行笔记页面的简单设置&#xff0c;但是我看了以后还是有点云里雾里&#xff0c;在一顿查阅资料以后&#xff0c;我终于找到了解决办法。 参考下面这个博主的文章。写得很详细&#xff0c;这里就不再赘述啦。 Stellar主题自定义侧边栏教…

通联历史数据如何自动化导入 DolphinDB

在部署完 DolphinDB 后&#xff0c;需要将历史数据批量导入数据库&#xff0c;再进行数据查询、计算和分析等操作。为便于用户快速导入通联历史 Level-2 行情数据&#xff0c;DolphinDB 开发了 DolphinDBModules::easyTLDataImport 模块&#xff08;简称 easyTLDataImport 模块…

Vue之事件修饰符

文章目录 前言一、事件修饰符二、实例1.prevent2.stop3.capture4.self 总结 前言 对事件进行处理。 一、事件修饰符 prevent&#xff1a;阻止默认事件&#xff08;常用&#xff09;。stop&#xff1a;阻止事件冒泡&#xff08;常用&#xff09;。once&#xff1a;事件只触发一…

Linux 系统下克隆 Github 项目指令

文章目录 1. 安装 git2. 设置用户名和邮箱3. 生成密钥4. 复制密钥5. 配置 Github SSH keys6. 克隆项目 1. 安装 git Ubuntu 安装指令 apt-get install gitCentOS 安装指令 yum install git 查看 Git 版本信息 git version2. 设置用户名和邮箱 git config --global user.nam…