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…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
