JAVA设计模式-策略模式及在Springboot2.X中写法

JAVA设计模式-策略模式及在Springboot2.X中写法

  • 一、经典的策略模式写法
  • 二、Springboot2.X中策略模式写法

策略模式的定义:策略模式是一种行为型设计模式,定义了一系列算法,并将每个算法封装起来,使它们可以互相替换
策略模式:在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。

如何解决:将这些算法封装成一个一个的类,任意地替换。

关键代码:实现同一个接口。

应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。

策略模式三种角色

  • 1、环境上下文(Context)角色:持有一个Strategy引用,委托策略变量调用具体策略所实现的策略接口中的方法。
  • 2、策略(Strategy)角色:抽象角色,通常由一个接口或抽象类实现,此角色给出所有的具体策略类所需接口。
  • 3、具体策略(ConcreteStrategy)角色:具体实现策略接口的类,包装了相关的算法或行为。

一、经典的策略模式写法

/*** 策略接口*/
public interface Strategy {int doOperation(int num1, int num2);
}/*** 加法策略*/
class OperationAdd implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}/*** 减法策略*/
class OperationSub implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}
}/*** 策略上下文类*/
class Context {private Strategy strategy;public Context(Strategy strategy) {this.strategy = strategy;}public Strategy getStrategy() {return strategy;}public void setStrategy(Strategy strategy) {this.strategy = strategy;}public int executeStrategy(int num1, int num2) {return strategy.doOperation(num1, num2);}
}class Main{public static void main(String[] args){// 策略上下文Context context = new Context(new OperationAdd());// 加法策略System.out.println("10 + 5 = " + context.executeStrategy(10, 5));// 减法策略context = new Context(new OperationSub());System.out.println("10 - 5 = " + context.executeStrategy(10, 5));}
}

但是上述的写法中,在具体使用过程中,要需要new具体的策略,而不能简单的传输一些字段来实现

二、Springboot2.X中策略模式写法

参考链接
在这里插入图片描述

在springboot中实现的时候可以采用@Component来标记为bean,通过获取bean来直接得到想要的具体策略

下述例子采用数据库存储的方式,将具体的code和beanId关联在一起,通过code–>获取beanId–>获取bean–>执行bean,从而不需要在Context中写if-else,或者在调用过程中写死new具体的策略

同理,使用 读取缓存、读取枚举、读取数据库等方式来实现,一定程度上解耦了抽象类和实体类之间的关联。
1.首先定义策略模式的策略接口

public interface Strategy {int doOperation(int num1, int num2);
}

2.定义具体的策略
在springboot中可以使用@Component标记一个类为组件

实现加法策略

@Component
public class OperationAdd implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 + num2;}
}

实现减法策略

@Component
class OperationSub implements Strategy {@Overridepublic int doOperation(int num1, int num2) {return num1 - num2;}
}

3.实现环境上下文Context

@Component
public class ContextStrategy {@Resourceprivate OperatorMapper operatorMapper;public int executeStrategy(int code,int num1, int num2) {OperatorEntity entity = OperatorMapper.getOperator(code);Strategy strategy = SpringUtils.getBean(entity.getStrategyBeanId(),Strategy.class);return strategy.doOperation(num1, num2);}
}

4.使用

@RestController
public class OperatorController {@Autowiredprivate ContextStrategy contextStrategy;@GetMapping("/toDoOperator")public String toDoOperator(String code,int num1,int num2){return contextStrategy.doOperation(code,num1,num2);}
}

5.细节部分

注意:这里有个细节问题,数据库存储的beanId一定要跟我们定义的bean保持一致,否则根据beanId去spring容器中获取实例对象会失败!
附根据beanId获取对应实例对象的utils

/*** 根据beanId 从spring容器中获取对象*/
@Component
public class SpringUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通过name获取 Bean.public static Object getBean(String name){return getApplicationContext().getBean(name);}//通过class获取Bean.public static <T> T getBean(Class<T> clazz){return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublic static <T> T getBean(String name,Class<T> clazz){return getApplicationContext().getBean(name, clazz);}}

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

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

相关文章

算法 java 排序和查找

排序和查找 冒泡排序&#xff08;稳定&#xff09;选择排序&#xff08;不稳定&#xff09;插入排序&#xff08;稳定&#xff09;希尔排序&#xff08;不稳定&#xff09;归并排序&#xff08;稳定&#xff09;快速排序&#xff08;不稳定&#xff09;堆排序计数排序桶排序基数…

YOLOv8+PyQt5海洋船只检测(可以重新训练,yolov8模型,从图像、视频和摄像头三种路径识别检测)

1.效果视频&#xff1a;海洋船只检测yoloV8检测&#xff08;https://mbd.pub/o/bread/mbd-ZpaYk55r&#xff09;_哔哩哔哩_bilibili资源包含可视化的海洋船只检测系统&#xff0c;可对于高空拍摄到的海洋图片进行轮船检测&#xff0c;基于最新的YOLOv8训练的海洋船只检测模型&a…

C++设计模式-策略模式,AI角色动态选择行为

运行在VS2022&#xff0c;x86&#xff0c;Debug下。 27. 策略模式 策略模式让算法的选择与使用独立开来&#xff0c;使得代码更灵活、可扩展和易维护。应用&#xff1a;如在游戏开发中&#xff0c;AI角色需要根据环境和条件做出不同的行为&#xff0c;如寻路、攻击、躲避等。可…

【安装笔记-20240529-Windows-Electerm 终端工具】

安装笔记-系列文章目录 安装笔记-20240529-Windows-Electerm 终端工具 文章目录 安装笔记-系列文章目录安装笔记-20240529-Windows-Electerm 终端工具 前言一、软件介绍名称&#xff1a;Wireshark主页官方介绍功能特性 二、安装步骤测试版本&#xff1a;electerm-1.39.35-win-…

【AIoT-Robot】3d hand pose

手语是聋哑人士的主要沟通工具,它是利用手部和身体的动作来传达意义。虽然手语帮助它的使用者之间互相沟通,但聋哑人士与一般人的沟通却十分困难,这个沟通障碍是源于大部分人不懂得手语。 1. 手势&&手语 手势:手的姿势 ,通常称作手势。它指的是人在运用手臂时,所…

初识springcloud

springcloud eureka eureka的作用 消费者该如何获取服务提供者具体信息&#xff1f; 服务提供者启动时向eureka注册自己的信息,eureka保存这些信息消费者,根据服务名称向eureka拉取提供者信息 如果有多个服务提供者&#xff0c;消费者该如何选择&#xff1f; 服务消费者利…

创建模块

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中&#xff0c;自定义模块有两个作用&#xff1a;一个是规范代码&#xff0c;让代码更易于阅读&#xff0c;另一个是方便其他程序使用已经编…

ORACLE创建dblink

dblink的作用 dblink数据库链接顾名思义就是数据库的链接&#xff0c;当我们要跨本地数据库&#xff0c;访问另外一个数据库表中的数据时&#xff0c;本地数据库中就必须要创建远程数据库的dblink&#xff0c;通过dblink本地数据库可以像访问本地数据库一样访问远程数据库表中…

Ubuntu22.04之解决:terminal使用alt+1/alt+2/alt+3失效问题(二百三十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

安卓玩机搞机技巧综合资源----电脑控制手机 投屏操控的软件工具操作步骤解析【二十二】

接上篇 安卓玩机搞机技巧综合资源------如何提取手机分区 小米机型代码分享等等 【一】 安卓玩机搞机技巧综合资源------开机英文提示解决dm-verity corruption your device is corrupt. 设备内部报错 AB分区等等【二】 安卓玩机搞机技巧综合资源------EROFS分区格式 小米红…

外发邮件监控的六种方法, 监控软件如何防止邮件泄密?

外发邮件监控的六种方法&#xff0c; 监控软件如何防止邮件泄密&#xff1f; 外发邮件监控是现代企业信息安全管理的重要组成部分&#xff0c;它有助于防止敏感信息泄露、保护知识产权、以及确保企业合规。以下是外发邮件监控的几种主要方法&#xff0c;这些方法结合使用可以为…

2024最新 Jenkins + Docker实战教程(八)- Jenkins实现集群并发构建

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

群体优化算法----人工蜂群优化算法应用于路径规划(机器人避开平面障碍寻找最短路线)

介绍 人工蜂群优化算法&#xff08;Artificial Bee Colony Algorithm, ABC&#xff09;是由Dervis Karaboga在2005年提出的一种模拟蜜蜂觅食行为的优化算法。该算法基于蜜蜂群体的分工合作和信息交流机制&#xff0c;通过模拟蜜蜂寻找食物源的过程来解决优化问题。ABC算法因其…

INT202 例题

算法复杂度 O(n)&#xff1a;表示算法的渐进上界。如果一个算法的运行时间是O(n)&#xff0c;那么它的运行时间最多与输入规模n成正比。换句话说&#xff0c;当输入规模n增加时&#xff0c;算法的运行时间不会超过某个常数倍的n。比如&#xff0c;如果一个算法的时间复杂度是O(…

打开常用C语言常用内存函数的大门 ——memcmp函数及其模拟实现(完结篇)

文章目录 1. 前言2. memcmp函数2.1 memcmp函数的原型2.2 memcmp的返回值2.2 memcmp的形参2.3 memcmp函数的使用 3. memcmp函数的模拟实现4. 总结 1. 前言 本文是C语言常用内存函数的最后一个函数 —— memcmp函数。 希望各位观众佬爷们能够学会并灵活的使用这四个常用的内存函…

平板显示LED背光芯片OC6700,输入3.6V~60V,升压型 LED 恒流驱动器

概述 OC6700是一款内置60V功率NMOS高效率、高精度的升压型大功率LED恒流驱动芯片。OC6700采用固定关断时间的控制方式&#xff0c;关断时间可通过外部电容进行调节&#xff0c;工作频率可根据用户要求而改变。OC6700通过调节外置的电流采样电阻&#xff0c;能控制高亮度LED灯的…

C语言之指针进阶(5),sizeof和strlen的数组计算以及指针运算笔试难题详解

目录 前言 一、sizeof和strlen 的区分比较 二、sizeof,strlen与数组的计算 三、指针运算&#xff0c;笔试难题解析 总结 前言 本文作为指针进阶的最后一篇文章&#xff0c;给大家带来了丰富的例题&#xff0c;这其中包括区分比较sizeof和strlen计算各种花样的数组指针表达式…

Redis的SDS数据结构解决C语言字符串缺陷

redis设计了SDS这一数据结构来表示字符串而不是使用c语言的字符串&#xff1a;字符数组 那么redis为什么要大费周章自己设计字符串呢&#xff1f; 答案是C语言字符串有缺陷 1.获取字符串长度&#xff0c;需要遍历字符数组&#xff0c;时间复杂度是O&#xff08;N&#xff09…

Springboot vue3 elementplus 景点评论数据分析与可视化系统源码

源码链接 系统演示:链接&#xff1a;https://pan.baidu.com/s/1J056R4rYji_mc4gwteZEzg?pwdnua4

教程 | 在 Navicat 17 中管理连接

Navicat 17 提供了比以往更多的连接数据库实例的方式。除了传统的连接字符串方式以外&#xff0c;Navicat 17 还支持 URI 连接&#xff0c;无论身在何处&#xff0c;都可以轻松地通过 URI 访问对象。另外&#xff0c;还有一个新的管理连接功能&#xff0c;即允许你通过一个以用…