java 策略模式 + 工厂模式 实例
一 前言
经常听说各种设计模式,知道理论,也知道应该使用,但具体怎么用,什么时候用,使用的优点一直比较模糊,今天写一个项目中经常用到的模式,来具体理解。项目中经常用到工厂模式或者策略模式,偶尔也会一起使用来增强代码管理,今天就一起使用来理解。
二 实现
不废话,直接上代码,最后解释
先写一个接口 Person 类
package com.fcy.demo.entity;public interface Person {void eat();void run();
}
然后使用策略模式,根据不同的人的类型,创建不同的人,实现该接口,这里有三种类型 Teacher, Doctor, Worker, 首先定义一个常量类,包含这三种类型的人。
package com.fcy.demo.constant;public class PersonType {public static final String TEACHER = "teacher";public static final String DOCTOR = "doctor";public static final String WORKER = "worker";
}
接着写三种人的实现类
package com.fcy.demo.entity;import com.fcy.demo.constant.PersonType;
import org.springframework.stereotype.Component;@Component(PersonType.TEACHER)
public class Teacher implements Person{@Overridepublic void eat() {System.out.println("老师吃");}@Overridepublic void run() {System.out.println("老师跑");}
}
package com.fcy.demo.entity;import com.fcy.demo.constant.PersonType;
import org.springframework.stereotype.Component;@Component(PersonType.DOCTOR)
public class Doctor implements Person{@Overridepublic void eat() {System.out.println("医生吃");}@Overridepublic void run() {System.out.println("医生跑");}
}
package com.fcy.demo.entity;import com.fcy.demo.constant.PersonType;
import org.springframework.stereotype.Component;@Component(PersonType.WORKER)
public class Worker implements Person{@Overridepublic void eat() {System.out.println("工人吃");}@Overridepublic void run() {System.out.println("工人跑");}
}
到此,为什么使用策略模式呢,因为如果不使用策略模式,所有代码都写在一个实现类里,当用户想让一个老师吃的时候,代码会变得比较繁琐,类似:
public void eat(PersonType type){if (PersonType.TEACHER.equals(type)){System.out.println("老师吃");} else if (PersonType.DOCTOR.equals(type)){System.out.println("医生吃");} else (PersonType.WORKER.equals(type)){System.out.println("工人吃");}
}
这里只有三种人,如果有十种甚至更多,会有更多的 if…else…, 同理对 run 操作也会有这么多的判断,实在难以维护,后续对某一类型的 eat 行为做更改时,也会影响其他代码,违背了开闭原则,即对扩展开放,对修改关闭。因此使用策略模式,使不同类型的人实现同一接口,当对某一类型的行为做更改时,不会影响其他类型的代码。
接下来说工厂模式
上面代码中重点是 @Component(PersonType.WORKER), 定义了 @Component 里的参数使得之后使用工厂模式时可以知道工厂该生产那种人。
到此,为什么使用工厂模式呢,如果不使用工厂模式,仅使用策略模式,同理当我想要一个老师吃的时候我需要自己实例一个老师类,类似下面代码:
public void eat(PersonType type){if (PersonType.TEACHER.equals(type)){Teacher teacher = new Teacher();teacher.eat();} else if (PersonType.DOCTOR.equals(type)){Doctor doctor = new Doctor();doctor.eat();} else (PersonType.WORKER.equals(type)){Worker worker = new Worker();worker.eat();}
}
虽然我们使用了策略模式,使代码满足开闭原则,易于维护,但并没有解决这么多 if…else… 的问题,所以我们使用工厂模式,减少判断,上代码:
package com.fcy.demo.factory;import com.fcy.demo.entity.Person;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class PersonFactor {@Autowiredprivate Map<String, Person> personTypeMap;public Person getPerson(String personType) {return personTypeMap.get(personType);}
}
至此我们就不需要这么多的判断了,当需要某种类型的人时,直接告诉工厂就可以了,controller 代码如下:
package com.fcy.demo.controller;import com.fcy.demo.entity.Person;
import com.fcy.demo.factory.PersonFactor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/person")
public class PersonController {@Autowiredpublic PersonFactor personFactor;@GetMapping("/teacher")public void getTeacher(){Person teacher = personFactor.getPerson("teacher");teacher.eat();}
}
启动代码,访问 http://localhost:8080/person/teacher, 发现控制台输出 “老师吃”, 测试成功,至此代码完成,也可以在 controller 中写其他的方法。
三 总结
在上面中解释了为什么使用 策略模式以及工厂模式,以及使用的优点,还有一个问题没有说,就是什么时候使用该模式, 在一类事物有共同的行为,但行为模式不同时就可以使用。
就到这吧,至此,关于 策略模式与工厂模式有了一个基本理解,也可以实现了。
相关文章:
java 策略模式 + 工厂模式 实例
一 前言 经常听说各种设计模式,知道理论,也知道应该使用,但具体怎么用,什么时候用,使用的优点一直比较模糊,今天写一个项目中经常用到的模式,来具体理解。项目中经常用到工厂模式或者策略模式&…...
本地生成动漫风格 AI 绘画 图像|Stable Diffusion WebUI 的安装和部署教程
Stable Diffusion WebUI 的安装和部署教程1. 简介2. Windows安装环境3. 运行4. 模型下载链接5. 其他资源1. 简介 先放一张WebUI的图片生成效果图,以给大家学习的动力 :) 怎么样,有没有小小的心动?这里再补充一下&…...
华为OD机试 - 异常的打卡记录 | 备考思路,刷题要点,答疑 【新解法】
最近更新的博客 【新解法】华为OD机试 - 关联子串 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 停车场最大距离 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 任务调度 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试…...
「机器学习笔记」之深度学习基础概念(基于Pytorch)
本文以 Pytorch 为线索,介绍人工智能和深度学习相关的一些术语、概念。 关于发展历史您也可以阅读深度学习神经网络之父 Jrgen Schmidhuber 所写的《Annotated History of Modern AI and Deep Learning(现代人工智能和深度学习的注释版历史)…...
概率和似然
在日常生活中,我们经常使用这些术语。但是在统计学和机器学习上下文中使用时,有一个本质的区别。本文将用理论和例子来解释概率和似然之间的关键区别。 概率与似然 假设在一场棒球比赛中,两队的队长都被召集到场上掷硬币。获胜的队长将根据掷…...
前期软件项目评估偏差,如何有效处理?
1、重新评估制定延期计划 需要对项目进行重新评估,将新的评估方案提交项目干系人会议,开会协商一致后按照新的讨论结果制定计划,并实施执行。 软件项目评估偏差 怎么办:重新评估制定延期计划2、申请加资源 如果项目客户要求严格&a…...
Xline v0.2.0: 一个用于元数据管理的分布式KV存储
Xline是什么?我们为什么要做Xline? Xline是一个基于Curp协议的,用于管理元数据的分布式KV存储。现有的分布式KV存储大多采用Raft共识协议,需要两次RTT才能完成一次请求。当部署在单个数据中心时,节点之间的延迟较低&a…...
CompletableFuture
一、一个示例回顾Future 一些业务场景我们需要使用多线程异步执行任务,加快任务执行速度。JDK5新增了Future接口,用于描述一个异步计算的结果。虽然Future以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,我们必须使用Future.get()的方式阻塞调…...
面试不到10分钟就被赶出来了,问的实在是太变态了...
干了两年外包,本来想出来正儿八经找个互联网公司上班,没想到算法死在另一家厂子。 自从加入这家外包公司,每天都在加班,钱倒是给的不少,所以也就忍了。没想到11月一纸通知,所有人不许加班,薪资…...
【C++】类与对象 (四)初始化列表 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化
前言 本章就是我们C中类与对象的终章了,不过本章的难度不大,都是类中一些边边角角的知识,记忆理解就行了,相信经过这么长时间的学习类与对象,你对面向对象也有了更加深的理解,最后我们学习完边边角角的一些…...
04:进阶篇 - 编译 CTK
作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 在使用 CTK 之前,首先要进行编译。但要成功编译它,并不是一件很容易的事,这不仅取决于平台、Qt 的版本,也取决于编译器,以及所使用的 IDE。 平台(Linux、Windows)Qt 版本(4.x、5.x、6.x)编译器(MS…...
SQL73 返回所有价格在 3美元到 6美元之间的产品的名称和价格
描述有表Productsprod_idprod_nameprod_pricea0011egg3a0019sockets4b0019coffee15【问题】编写 SQL 语句,返回所有价格在 3美元到 6美元之间的产品的名称(prod_name)和价格(prod_price),使用 AND操作符&am…...
【Linux 多线程互斥】如何保证锁的原子性(互斥的原理)
临界资源:可以被多个执行流(线程或者叫轻量级进程)同是访问的(多个执行流共享的,比如:全局、堆等等);临界区:访问这些临界资源的代码;原子性:没有中间态&…...
Android 实现沉浸式全屏
前言 本文总结 Android 实现沉浸式全屏的实现方式。 实现沉浸式全屏 在一些需要全屏显示的场景下,比如玩游戏、看横屏视频的时候,内容全屏,占满窗口的体验会让用户更加沉浸到对内容的消费中,带来好的用户体验。 沉浸式显示具体来说就是如状态栏和导航栏部分的显示效果调…...
数据分析与SAS学习笔记6
数据集整理: 目的:对数据集中的数据进行预处理,使数据更适合统计分析过程对数据格式的要求; 常见整理要求: 1)建立新的变量,衍生变量,删除某些原变量; 2)…...
自动化完成1000个用户的登录并获取token并生成tokens.txt文件
自动化完成1000个用户的登录并获取token并生成tokens.txt文件 写作背景 在我学习使用redis实现秒杀功能的过程中,在编写完秒杀代码后,需要使用Jmeter实际测试1000个用户进行秒杀,由于秒杀功能需要在用户登录完成后才能实现,用户是…...
2023年全国最新安全员精选真题及答案1
百分百题库提供安全员考试试题、建筑安全员考试预测题、建筑安全员ABC考试真题、安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 11.(单选题)在起重作业中,()…...
NoMachine 输入用户名密码后 闪断 解决办法
大家好,我是虎哥,最近工作忙,好长时间没有继续套件的深度学习,今天周六,难得有空,泡好茶,打开电脑,链接套件桌面,得,出问题了,一个很奇怪的问题&a…...
WebADI - 参数的使用
* 本文仅供交流分享,不作为专业指导 最近研究了一下WEBADI文档下载的参数,由于网上这块资料较少,所以专意分享下我的笔记。 准备 集成器:BHSC_EMP_ADI 表值集:BHSC_DEPT_LOV(值:dname&#x…...
【OJ】两个圆
📚Description: 直角坐标系内现有两个半径相等的圆,问两圆的位置关系。 位置关系有:重合,相切,相离,相交; 若两圆相交,需要求出两圆的重叠面积。 ⏳Input: 输入包含多组数据&a…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”
2025年#高考 将在近日拉开帷幕,#AI 监考一度冲上热搜。当AI深度融入高考,#时间同步 不再是辅助功能,而是决定AI监考系统成败的“生命线”。 AI亮相2025高考,40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕,江西、…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
STM32---外部32.768K晶振(LSE)无法起振问题
晶振是否起振主要就检查两个1、晶振与MCU是否兼容;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容(CL)与匹配电容(CL1、CL2)的关系 2. 如何选择 CL1 和 CL…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
