当前位置: 首页 > news >正文

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 策略模式 + 工厂模式 实例

一 前言 经常听说各种设计模式&#xff0c;知道理论&#xff0c;也知道应该使用&#xff0c;但具体怎么用&#xff0c;什么时候用&#xff0c;使用的优点一直比较模糊&#xff0c;今天写一个项目中经常用到的模式&#xff0c;来具体理解。项目中经常用到工厂模式或者策略模式&…...

本地生成动漫风格 AI 绘画 图像|Stable Diffusion WebUI 的安装和部署教程

Stable Diffusion WebUI 的安装和部署教程1. 简介2. Windows安装环境3. 运行4. 模型下载链接5. 其他资源1. 简介 先放一张WebUI的图片生成效果图&#xff0c;以给大家学习的动力 &#xff1a;&#xff09; 怎么样&#xff0c;有没有小小的心动&#xff1f;这里再补充一下&…...

华为OD机试 - 异常的打卡记录 | 备考思路,刷题要点,答疑 【新解法】

最近更新的博客 【新解法】华为OD机试 - 关联子串 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 停车场最大距离 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试 - 任务调度 | 备考思路,刷题要点,答疑,od Base 提供【新解法】华为OD机试…...

「机器学习笔记」之深度学习基础概念(基于Pytorch)

本文以 Pytorch 为线索&#xff0c;介绍人工智能和深度学习相关的一些术语、概念。 关于发展历史您也可以阅读深度学习神经网络之父 Jrgen Schmidhuber 所写的《Annotated History of Modern AI and Deep Learning&#xff08;现代人工智能和深度学习的注释版历史&#xff09;…...

概率和似然

在日常生活中&#xff0c;我们经常使用这些术语。但是在统计学和机器学习上下文中使用时&#xff0c;有一个本质的区别。本文将用理论和例子来解释概率和似然之间的关键区别。 概率与似然 假设在一场棒球比赛中&#xff0c;两队的队长都被召集到场上掷硬币。获胜的队长将根据掷…...

前期软件项目评估偏差,如何有效处理?

1、重新评估制定延期计划 需要对项目进行重新评估&#xff0c;将新的评估方案提交项目干系人会议&#xff0c;开会协商一致后按照新的讨论结果制定计划&#xff0c;并实施执行。 软件项目评估偏差 怎么办&#xff1a;重新评估制定延期计划2、申请加资源 如果项目客户要求严格&a…...

Xline v0.2.0: 一个用于元数据管理的分布式KV存储

Xline是什么&#xff1f;我们为什么要做Xline&#xff1f; Xline是一个基于Curp协议的&#xff0c;用于管理元数据的分布式KV存储。现有的分布式KV存储大多采用Raft共识协议&#xff0c;需要两次RTT才能完成一次请求。当部署在单个数据中心时&#xff0c;节点之间的延迟较低&a…...

CompletableFuture

一、一个示例回顾Future 一些业务场景我们需要使用多线程异步执行任务,加快任务执行速度。JDK5新增了Future接口,用于描述一个异步计算的结果。虽然Future以及相关使用方法提供了异步执行任务的能力,但是对于结果的获取却是很不方便,我们必须使用Future.get()的方式阻塞调…...

面试不到10分钟就被赶出来了,问的实在是太变态了...

干了两年外包&#xff0c;本来想出来正儿八经找个互联网公司上班&#xff0c;没想到算法死在另一家厂子。 自从加入这家外包公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到11月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资…...

【C++】类与对象 (四)初始化列表 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化

前言 本章就是我们C中类与对象的终章了&#xff0c;不过本章的难度不大&#xff0c;都是类中一些边边角角的知识&#xff0c;记忆理解就行了&#xff0c;相信经过这么长时间的学习类与对象&#xff0c;你对面向对象也有了更加深的理解&#xff0c;最后我们学习完边边角角的一些…...

04:进阶篇 - 编译 CTK

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 在使用 CTK 之前,首先要进行编译。但要成功编译它,并不是一件很容易的事,这不仅取决于平台、Qt 的版本,也取决于编译器,以及所使用的 IDE。 平台(Linux、Windows)Qt 版本(4.x、5.x、6.x)编译器(MS…...

SQL73 返回所有价格在 3美元到 6美元之间的产品的名称和价格

描述有表Productsprod_idprod_nameprod_pricea0011egg3a0019sockets4b0019coffee15【问题】编写 SQL 语句&#xff0c;返回所有价格在 3美元到 6美元之间的产品的名称&#xff08;prod_name&#xff09;和价格&#xff08;prod_price&#xff09;&#xff0c;使用 AND操作符&am…...

【Linux 多线程互斥】如何保证锁的原子性(互斥的原理)

临界资源:可以被多个执行流&#xff08;线程或者叫轻量级进程&#xff09;同是访问的&#xff08;多个执行流共享的&#xff0c;比如&#xff1a;全局、堆等等&#xff09;&#xff1b;临界区&#xff1a;访问这些临界资源的代码&#xff1b;原子性&#xff1a;没有中间态&…...

Android 实现沉浸式全屏

前言 本文总结 Android 实现沉浸式全屏的实现方式。 实现沉浸式全屏 在一些需要全屏显示的场景下,比如玩游戏、看横屏视频的时候,内容全屏,占满窗口的体验会让用户更加沉浸到对内容的消费中,带来好的用户体验。 沉浸式显示具体来说就是如状态栏和导航栏部分的显示效果调…...

数据分析与SAS学习笔记6

数据集整理&#xff1a; 目的&#xff1a;对数据集中的数据进行预处理&#xff0c;使数据更适合统计分析过程对数据格式的要求&#xff1b; 常见整理要求&#xff1a; 1&#xff09;建立新的变量&#xff0c;衍生变量&#xff0c;删除某些原变量&#xff1b; 2&#xff09;…...

自动化完成1000个用户的登录并获取token并生成tokens.txt文件

自动化完成1000个用户的登录并获取token并生成tokens.txt文件 写作背景 在我学习使用redis实现秒杀功能的过程中&#xff0c;在编写完秒杀代码后&#xff0c;需要使用Jmeter实际测试1000个用户进行秒杀&#xff0c;由于秒杀功能需要在用户登录完成后才能实现&#xff0c;用户是…...

2023年全国最新安全员精选真题及答案1

百分百题库提供安全员考试试题、建筑安全员考试预测题、建筑安全员ABC考试真题、安全员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 11.&#xff08;单选题&#xff09;在起重作业中&#xff0c;&#xff08;&#xff09…...

NoMachine 输入用户名密码后 闪断 解决办法

大家好&#xff0c;我是虎哥&#xff0c;最近工作忙&#xff0c;好长时间没有继续套件的深度学习&#xff0c;今天周六&#xff0c;难得有空&#xff0c;泡好茶&#xff0c;打开电脑&#xff0c;链接套件桌面&#xff0c;得&#xff0c;出问题了&#xff0c;一个很奇怪的问题&a…...

WebADI - 参数的使用

* 本文仅供交流分享&#xff0c;不作为专业指导 最近研究了一下WEBADI文档下载的参数&#xff0c;由于网上这块资料较少&#xff0c;所以专意分享下我的笔记。 准备 集成器&#xff1a;BHSC_EMP_ADI 表值集&#xff1a;BHSC_DEPT_LOV&#xff08;值&#xff1a;dname&#x…...

【OJ】两个圆

&#x1f4da;Description: 直角坐标系内现有两个半径相等的圆&#xff0c;问两圆的位置关系。 位置关系有&#xff1a;重合&#xff0c;相切&#xff0c;相离&#xff0c;相交&#xff1b; 若两圆相交&#xff0c;需要求出两圆的重叠面积。 ⏳Input: 输入包含多组数据&a…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化

是不是受够了安装了oracle database之后sqlplus的简陋&#xff0c;无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话&#xff0c;配置.bahs_profile后也能解决上下翻页这些&#xff0c;但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可&#xff0c…...

Pydantic + Function Calling的结合

1、Pydantic Pydantic 是一个 Python 库&#xff0c;用于数据验证和设置管理&#xff0c;通过 Python 类型注解强制执行数据类型。它广泛用于 API 开发&#xff08;如 FastAPI&#xff09;、配置管理和数据解析&#xff0c;核心功能包括&#xff1a; 数据验证&#xff1a;通过…...