设计模式 模板方法模式

01.如果接到一个任务,要求设计不同型号的悍马车
在这里插入图片描述
02.设计一个悍马车的抽象类(模具,车模)

public abstract class HummerModel {/** 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正* 是要能够发动起来,那这个实现要在实现类里了*/public abstract void start(); //能发动,那还要能停下来,那才是真本事public abstract void stop(); //喇叭会出声音,是滴滴叫,还是哔哔叫public abstract void alarm(); //引擎会轰隆隆的响,不响那是假的public abstract void engineBoom(); //那模型应该会跑吧,别管是人推的,还是电力驱动,总之要会跑public abstract void run(); 
} 

03.具体不同版本的悍马,这个是抽象类的具体子类

H1 型号悍马的定义如下:

public class HummerH1Model extends HummerModel { @Override public void alarm() { System.out.println("悍马H1鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H1引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H1发动..."); }@Overridepublic void stop() { System.out.println("悍马H1停车..."); } /** 这个方法是很有意思的,它要跑,那肯定要启动,停止了等,也就是要调其他方法*/@Overridepublic void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
} 

然后看悍马 H2 型号的实现:

public class HummerH2Model extends HummerModel { @Overridepublic void alarm() { System.out.println("悍马H2鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H2引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H2发动..."); } @Overridepublic void stop() { System.out.println("悍马H1停车..."); } /** H2要跑,那肯定要启动,停止了等,也就是要调其他方法*/@Overridepublic void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
}

然后程序写到这里,你就看到问题了,run 方法的实现应该在抽象类上(子类改写的都一样),不应该在实现类上,好,我们修改一下类图和实现:
在这里插入图片描述

就把 run 方法放到了抽象类中,那代码也相应的改变一下,先看 HummerModel.java:

04.修改后的抽象类

public abstract class HummerModel { /** 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正* 是要能够发动起来,那这个实现要在实现类里了*/public abstract void start(); //能发动,那还要能停下来,那才是真本事public abstract void stop(); //喇叭会出声音,是滴滴叫,还是哔哔叫public abstract void alarm(); //引擎会轰隆隆的响,不响那是假的public abstract void engineBoom(); //那模型应该会跑吧,别管是人退的,还是电力驱动,总之要会跑public void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
}

05.修改后的抽象类的子类:

public class HummerH1Model extends HummerModel { @Override public void alarm() { System.out.println("悍马H1鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H1引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H1发动..."); }@Overridepublic void stop() { System.out.println("悍马H1停车..."); } } 
public class HummerH2Model extends HummerModel { @Overridepublic void alarm() { System.out.println("悍马H2鸣笛..."); } @Overridepublic void engineBoom() { System.out.println("悍马H2引擎声音是这样在..."); } @Overridepublic void start() { System.out.println("悍马H2发动..."); } @Overridepublic void stop() { System.out.println("悍马H2停车..."); } }

06.运行程序
在这里插入图片描述

public class Client { public static void main(String[] args) { //客户开着H1型号,出去遛弯了HummerModel h1 = new HummerH1Model(); h1.run(); //汽车跑起来了;//客户开H2型号,出去玩耍了HummerModel h2 = new HummerH2Model(); h2.run(); } 
}

在这里插入图片描述

07.客户只要在 run 的过程中,听到或看都成了呀,暴露那么多的方法干啥?把抽象方法保护起来
在这里插入图片描述
把抽象类上的四个方法设置为 protected 访问权限,好了,既然客户不关心这几个方法,而且这四个方法都是由子类来实现的,那就设置成 protected 模式。咦~,那还有个缺陷,run 方法既然子类都不修改,那是不是可以设置成 final 类型呢?是滴是滴,类图如下:
在这里插入图片描述

public abstract class HummerModel { /** 首先,这个模型要能够被发动起来,别管是手摇发动,还是电力发动,反正* 是要能够发动起来,那这个实现要在实现类里了*/protected abstract void start(); //能发动,那还要能停下来,那才是真本事protected abstract void stop(); //喇叭会出声音,是滴滴叫,还是哔哔叫protected abstract void alarm(); //引擎会轰隆隆的响,不响那是假的protected abstract void engineBoom(); //那模型应该会跑吧,别管是人退的,还是电力驱动,总之要会跑final public void run() { //先发动汽车this.start(); //引擎开始轰鸣this.engineBoom(); //然后就开始跑了,跑的过程中遇到一条狗挡路,就按喇叭this.alarm(); //到达目的地就停车this.stop(); } 
} 

大家请看这个 run 方法,他定义了调用其他方法的顺序,并且子类是不能修改的,这个叫做模板方法;start、stop、alarm、engineBoom 这四个方法是子类必须实现的,而且这四个方法的修改对应了不同的类,这个叫做基本方法,基本方法又分为三种:在抽象类中实现了的基本方法叫做具体方法;在抽象类中没有实现,在子类中实现了叫做抽象方法,我们这四个基本方法都是抽象方法,由子类来实现的;还有一种叫做钩子方法,

“客户提出新要求了,那个喇叭想让它响就响,你看你设计的模型,车子一启动,喇叭就狂响,赶快修改一下”,确实是设计缺陷,呵呵,不过是我故意的,那我们怎么修改呢?看修改后的类图:

在这里插入图片描述

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

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

相关文章

39 openlayers 对接地图图层 绘制点线面圆

前言 这里主要是展示一下 openlayers 的一个基础的使用 主要是设计 接入地图服务器的 卫星地图, 普通的二维地图, 增加地区标记 增加 省市区县 的边界标记 基础绘制 点线面园 等等 测试用例 <template><div style"width: 1920px; height:1080px;" &g…

前端canvas项目实战——简历制作网站(六):加粗、斜体、下划线、删除线(上)

目录 前言一、效果展示二、实现步骤1. 视图部分&#xff1a;实现用于切换字体属性的按钮2. 逻辑部分&#xff1a;点击按钮之后要做什么&#xff1f;3. 根据Textbox的属性实时更新按钮的状态 三、Show u the code后记 前言 上一篇博文中&#xff0c;我们实现了对文字的字体、字…

优化选址问题 | 基于灰狼算法求解基站选址问题含Matlab源码

目录 问题代码问题 灰狼优化算法(Grey Wolf Optimizer, GWO)是一种基于自然界中灰狼群体狩猎行为的优化算法。这种算法通过模拟灰狼的社会等级和狩猎行为来寻找问题的最优解。 基站选址问题通常是一个多目标优化问题,涉及到覆盖范围、信号质量、成本等多个因素。使用灰狼算…

web服务架构

1 Web服务器&#xff08;如Nginx、Apache等&#xff09;和Web应用框架&#xff08;如Flask、Django等&#xff09; Web服务器&#xff08;如Nginx、Apache等&#xff09;和Web应用框架&#xff08;如Flask、Django等&#xff09;在Web应用开发和部署中扮演着不同的角色&#xf…

软考中级 --网络工程师真题试卷 2023下半年

在EIGRP协议中&#xff0c;某个路由器收到了两条路径到达目标网络&#xff0c;路径1的带宽为100Mbps&#xff0c;延迟2ms&#xff0c;路径2的带宽为50Mbps&#xff0c;迟为4ms&#xff0c;如果EIGRP使用带宽和延迟的综合度量标准&#xff0c;那么该路由器选择的最佳路径是(D)。…

Codeforces Round 930 (Div. 2)(A,B,C,D)

比赛链接 C是个交互&#xff0c;D是个前缀和加二分。D还是很难写的。 A. Shuffle Party 题意&#xff1a; 您将得到一个数组 a 1 , a 2 , … , a n a_1, a_2, \ldots, a_n a1​,a2​,…,an​ 。最初&#xff0c;每个 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n 对应 a i i a_ii…

win10 禁止谷歌浏览器自动更新(操作贼简单)

禁止谷歌浏览器自动更新 &#xff08;1&#xff09;修改 "C:\Windows\System32\drivers\etc\hosts 文件&#xff0c;在最后增加 127.0.0.1 update.googleapis.com&#xff08;2&#xff09;保存后&#xff0c;winr 快捷键&#xff0c;输入cmd &#xff0c;打开命令行 &am…

AJAX踩坑指南(知识点补充)

JWT JSON Web Token是目前最为流行的跨域认证解决方案 如何获取&#xff1a;在使用JWT身份验证中&#xff0c;当用户使用其凭据成功登录时&#xff0c;将返回JSON Web Token(令牌&#xff09; Token本质就是一个包含了信息的字符串 如何获取Token:登录成功之后&#xff0c;服务…

Springboot解决跨域问题方案总结(包括Nginx,Gateway网关等)

&#x1f3f7;️个人主页&#xff1a;牵着猫散步的鼠鼠 &#x1f3f7;️系列专栏&#xff1a;Java全栈-专栏 &#x1f3f7;️个人学习笔记&#xff0c;若有缺误&#xff0c;欢迎评论区指正 目录 前言 解决跨域问题方案 1.Spring Boot 中解决跨域 1.1 通过注解跨域 1.2 通…

什么是RabbitMQ的死信队列

RabbitMQ的死信队列&#xff08;Dead Letter Queue&#xff0c;简称DLQ&#xff09;是一种用于处理消息失败或无法路由的消息的机制。它允许将无法被正常消费的消息重新路由到另一个队列&#xff0c;以便稍后进行进一步处理、分析或排查问题。 当消息对立里面的消息出现以下几…

深度学习基础之《TensorFlow框架(10)—案例:实现线性回归(2)》

增加其他功能 一、增加变量显示 1、目的&#xff1a;在TensorBoard当中观察模型的参数、损失值等变量值的变化 2、收集变量 不同的变量要用不同的方式收集 &#xff08;1&#xff09;tf.summary.scalar(name, tensor) 收集对于损失函数和准确率等单值变量&#xff0c;name为…

Spring Boot 自动化单元测试类的编写过程

前言 Web环境模拟测试 企业开发不仅要保障业务层与数据层的功能安全有效&#xff0c;也要保障表现层的功能正常。但是我们一般对表现层的测试都是通过postman手工测试的&#xff0c;并没有在打包过程中代码体现表现层功能被测试通过。那么能否在测试用例中对表现层进行功能测…

LabVIEW高效光伏数据监控与管理系统

LabVIEW高效光伏数据监控与管理系统 随着新能源技术的发展&#xff0c;光伏发电系统作为一种清洁、高效的能源获取方式受到了广泛的关注。但是&#xff0c;由于光伏发电的特性受到多种环境因素的影响&#xff0c;其运行效率和安全性成为了关键问题。因此&#xff0c;开发一个高…

K8S--SpringCloud应用整合Nacos实战

原文网址&#xff1a;K8S--SpringCloud应用整合Nacos实战-CSDN博客 简介 本文介绍K8S部署SpringCloud应用整合Nacos实战。 本文是将原来的SpringCloud项目&#xff08;闪速优选&#xff09;迁移到K8S上&#xff0c;一行代码都不需要改动。用K8S运行Nacos、Gateway、SpringCl…

Mac nvm install failed python: not found

报错 $>./configure --prefix/Users/xxx/.nvm/versions/node/v12.22.12 < ./configure: line 3: exec: python: not found nvm: install v12.22.12 failed!解决方法 到 App 文件夹&#xff0c;并且打开 cd /System/Applications/Utilities/ open .记得改完 Rosetta 之…

模拟-算法

文章目录 替换所有的问号提莫攻击Z字形变换外观数列数青蛙 替换所有的问号 算法思路&#xff1a; 从前往后遍历整个字符串&#xff0c;找到问号之后&#xff0c;就遍历 a ~ z 去尝试替换即可。 class Solution {public String modifyString(String s) {char[] ss s.toCharA…

mac下 3.6.3 版本 maven

问题 Blocked mirror for repositories: [snapshots (http://xxx/artifactory/gm-maven-vir, default, releasessnapshots)]无法访问 Maven 3.8.1 http 仓库。可能的解决方案: - 检查 Maven settings.xml 是否不包含 http 仓库 - 检查 Maven pom 文件是否不包含 http 仓库 htt…

bs4的基本使用

下载基本使用标签定位标签属性定位选择器定位数据的提取 下载 pip install bs4 pip install lxml基本使用 from bs4 import BeautifulSoup #1.创建一个BeautifulSoup的工具对象&#xff0c;然后把即将被解析的页面源码数据加载到该对象中#参数1&#xff1a;被解析的页面源码数…

【STM32嵌入式系统设计与开发】——6矩阵按键应用(4x4)

这里写目录标题 一、任务描述二、任务实施1、SingleKey工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#xff08;2&#xff09;LED IO初始化函数(LED_Init())&#xff08;3&#xff09;开发板矩阵键盘IO初始化&#xff08;ExpKeyBordInit()&#xff09;&…

【管理咨询宝藏56】大型德企业务战略规划报告

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏56】大型德企业务战略规划报告 【格式】PDF 【关键词】战略规划、商业分析、管理咨询 【核心观点】 - 这是一份非常完整的知名德企在华业务战略…