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…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
算法打卡第18天
从中序与后序遍历序列构造二叉树 (力扣106题) 给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。 示例 1: 输入:inorder [9,3,15,20,7…...
若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
