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 {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

/**
 * 减法策略
 */
class OperationSub implements Strategy {
    @Override
    public 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 {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

实现减法策略

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

3.实现环境上下文Context

@Component
public class ContextStrategy {

    @Resource
    private 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 {
    @Autowired
    private 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;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    //获取applicationContext
    public 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返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【已解决】记录Vue2.x中npm install下载依赖报错:python2 Error: not found: python2问题(具体操作步骤)

项目场景&#xff1a; 项目场景&#xff1a;在项目开发中&#xff0c;升级了本地node版本后&#xff0c;重新npm install下载依赖报错找不到python环境 not found: python2 npm ERR! gyp verb check python checking for Python executable “python2” in the PATH 在尝试了各…

k8s——pod集群调度及相关操作

一、集群调度概念 1.1 调度约束&#xff08;List-Watch&#xff09; Kubernetes是通过List-Watch的机制进行每个组件的协作&#xff0c;保持数据同步的&#xff0c;每个组件之间的设计实现了解耦。 用户是通过kubectl根据配置文件&#xff0c;向APIServer发送命令&#xff0c;在…

进入mysql报错:bash:/bin/mysql:没有那个文件或目录

问题分析&#xff1a; 有可能把/bin下面的mysql文件删除 解决方案&#xff1a; 卸载已安装MySQL&#xff0c;重新安装一遍 卸载步骤&#xff1a; 在CentOS系统中卸载MySQL可以通过以下步骤进行&#xff1a; 1、停止MySQL服务&#xff1a; sudo systemctl stop mysqld 2…

QT 音乐播放器【二】 歌词同步+滚动+特效

文章目录 效果图概述代码解析歌词歌词同步歌词特效 总结 效果图 概述 先整体说明一下这个效果的实现&#xff0c;你所看到的歌词都是QGraphicsObject&#xff0c;在QGraphicsView上绘制(paint)出来的。也就是说每一句歌词都是一个图元(item)。 为什么用QGraphicsView框架&…

【JS实战02】轮播图

一&#xff1a;HTML页面结构 1 整体外观 2 HTML结构以及CSS样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

HTML静态网页成品作业(HTML+CSS)—— 美食湘菜介绍网页(5个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有5个页面。 二、作品演示 三、代…

ROS2从入门到精通4-3:全局路径规划插件开发案例(以A*算法为例)

目录 0 专栏介绍1 路径规划插件的意义2 全局规划插件编写模板2.1 构造规划插件类2.2 注册并导出插件2.3 编译与使用插件 3 全局规划插件开发案例(A*算法)常见问题 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有机器人建…

基于WPF开发动态可交互混淆矩阵

最近在项目中&#xff0c;为了算法结果的可视化&#xff0c;需要用到混淆矩阵(Confusion Matrix)&#xff0c;而网上资源大多是基于Python绘制的混淆矩阵&#xff0c;并且是输出图片格式&#xff0c;并不能响应用户点击&#xff0c;今天以一个简单的小例子&#xff0c;简述如何…

正序输入一串数,倒序输出,c语言

正序输入一串数&#xff0c;倒序输出 #include <stdio.h> int main () {int i,a[5]; for(i0;i<5;i) {scanf("%d",&a[i]);} for(i4;i>0;i--) {printf("%d",a[i]);} printf("\n"); return 0; } 运行结果

三分钟“手撕”队列与习题

代码放开头&#xff0c;方便大家查阅 目录 一、实现代码 二、什么是队列 三、队列常见方法 入队push&#xff08;&#xff09; 出队 四、Queue使用 Java自带的Queue 双端队列 五、习题 循环队列 用队列实现栈 用栈实现队列 一、实现代码 package demo2;publi…

【leetcode10-21】子串、普通数组、矩阵

子串 560.和为K的子数组【没理解】 什么是前缀和&#xff1a;前缀和指一个数组的某下标之前的所有数组元素的和&#xff08;包含其自身&#xff09; 通常&#xff0c;会在前缀和首位放一个0。比如数组[1,2,3。其前缀和是[0,1,3,6] 前缀和通常可以帮助我们快速计算某个区间内的…

【控制实践——四旋翼无人机】【一】四旋翼无人机运动分析和建模

传送门 系列博客前言坐标系定义及姿态位置描述坐标系定义姿态描述及坐标系变换 受力分析牛顿-欧拉方程状态空间方程总结 系列博客 前言 在C站摸爬滚打一段时间后&#xff0c;发现控制类相关的圈子较小&#xff08;话题热度低&#xff09;&#xff0c;想顺便跟各位同行读者了解…

Netty是什么?深入理解高性能网络框架

Netty是什么&#xff1f;——深入理解高性能网络框架 引言 在现代互联网应用中&#xff0c;网络通信是不可或缺的一部分。无论是构建微服务架构、游戏服务器、实时通信系统还是物联网应用&#xff0c;高效稳定的网络编程框架都是成功的关键。Netty&#xff0c;作为一款高性能…

项目:仿RabbitMQ实现的消息队列组件

文章目录 写在前面开源仓库和项目上线其他文档说明 需求分析BrokerServer交换机类型持久化消息应答 模块划分服务端模块客户端模块交换机数据管理模块队列数据管理模块绑定数据管理模块消息数据管理模块队列信息管理模块虚拟机数据管理模块路由匹配模块消费者管理模块信道管理模…

HTML+CSS+JS 选项卡导航栏

效果演示 实现了一个导航栏切换内容的效果。页面上方有一个导航栏,每个导航项都有一个圆形背景,点击导航项时,圆形背景会放大并显示对应的内容。每个内容区域都包含一个大号字母,数字会在内容区域显示时淡入。点击其他导航项时,当前内容区域会淡出并隐藏,同时新的内容区域…

[数据集][目标检测]csgo头部身体检测数据集VOC+YOLO格式1265张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;1265 标注数量(xml文件个数)&#xff1a;1265 标注数量(txt文件个数)&#xff1a;1265 标注…

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

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

mybatis—plus和mybatis的区别

一前置知识&#xff1a; CRUD操作&#xff08;create 添加数据read读取数据 update 修改数据delete删除数据&#xff09; 二&#xff0c;总体概览 MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发工作、提高…

INT202 例题

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

【InternLM实战营第二期笔记】04:XTuner 微调 LLM:1.8B、多模态、Agent

文章目录 笔记微调基础知识Xtuner8G显存微调模型InternLM2 1.8B多模态实践环节数据微调过拟合WebUI 交互 多模态微调 作业 这回学乖了&#xff0c;打开本节课第一件事先不看教程而是装环境~ 笔记 微调基础知识 这里感慨一下&#xff0c;垂直领域的训练还是挺困难的&#xff0c;…