百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

【设计模式】SpringBoot优雅使用策略模式

wxin55 2024-11-06 12:49 11 浏览 0 评论

文章目录

1.概述

1.1.简述策略模式

2.实现方法

2.1.实现思路

2.2.实现代码

2.3.策略拓展

2.4.执行调用

3.总结

1.概述

本篇文章主要会描述SpringBoot与策略模式的结合使用,因为不涉及到理论部分,所以在阅读本篇之前,需要对策略模式的理论已经有了一个基本的了解。

1.1.简述策略模式

策略模式有3种角色,分别为:选择器、抽象策略、策略实例。

其中选择器selector又被称为上下文context,其作用为通过不同的标识来获取对应的策略实例。策略实例就是封装不同算法的实例对象,而抽象策略就是策略实例的顶层接口。

简单类图大概就是这个样子:



2.实现方法

我们在学习设计模式的时候会发现在各类模式中的类与对象都是手动创建的,而在日常的开发中,我们往往会将对象的生命周期交给Spring管理,也就是说,需要我们自行将各类bean组合成一个可运行的设计模式。

假设我们有这样一个场景,需要对系统的中的数据做统计,需求中的统计维度分为:按周统计、按月统计,现使用策略模式来实现这个需求。

2.1.实现思路

前置设计:通过定义常量来标识策略的类型,使用者调用时可以通过常量获取对应的策略实例。

策略设计:按周、按月分别对应两个bean实例,在内部各自实现对应的统计维度逻辑,在两个bean实例的上层是抽象策略,有一个通用的接口(或抽象类)用于对外提供访问入口。

选择器设计:可以通过Map来存储数据,调用者调用时可以通过策略标识来获取对应的策略实例。

可以看到,实现思路是比较简单的,现在的问题就是如何把策略的bean实例对象放到Map中。

最简单的方式当然就是把对应的bean的Class对象直接写死在Map中,调用的时候可以通过applicationContext.getBean()获取到bean实例。但是这种方式不利于拓展,后续要新增一个策略实例的时候,还得修改这里的Map。

第二种方式,我们可以通过解析注解来实现,给每个策略实例打上一个注解,注解中的值对应的就是按周、按月这样的常量标识,在SpringBoot启动时,通过扩展点扫描抽象策略,获取它所有的策略实例,解析注解后放入Map中。这种方式利于拓展,新增一个策略实例不需要对旧代码有任何改动。

2.2.实现代码

这里原本是使用自定义注解来实现的,经过评论区的提醒,对于注解实现这种方式,通过Spring中自带的@Component注解来实现会更加简洁,下面是去掉了自定义注解的实现方式。

第一步:编写抽象策略与策略实例

/**
* 统计抽象策略处理器
*/
public interface StatisticBaseHandler {
void doStatistic();
}
import org.springframework.stereotype.Component;
/**
* 月统计策略
*/
@Component("month")
public class StatisticByMonthHandler implements StatisticBaseHandler {
@Override
public void doStatistic() {
System.out.println("StatisticByMonthHandler");
}
}

import org.springframework.stereotype.Component;
/**
* 周统计策略
*/
@Component("week")
public class StatisticByWeekHandler implements StatisticBaseHandler {
@Override
public void doStatistic() {
System.out.println("StatisticByWeekHandler");
}
}

第二步:编写选择器

这里直接使用@Resouce或者@Autowired注入一个Map。

import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Map;
/**
* 统计策略选择器
*/
@Component
public class StatisticStrategySelector {
@Resource
private Map<String, StatisticBaseHandler> selectorMap;
/**
* 根据类型选择对应的策略
*
* @param type 统计周期类型
* @return 统计抽象策略处理器
*/
public StatisticBaseHandler select(String type) {
return selectorMap.get(type);
}
}

启动完成之后,Map中的key值为@Component中配置的key。

2.3.策略拓展

现在需求发生了变化,需要加入一个按年统计的策略类型,只需要新增一个策略实例即可,如下:

import org.springframework.stereotype.Component;
/**
* 年统计策略
*/
@Component("year")
public class StatisticByYearHandler implements StatisticBaseHandler {
@Override
public void doStatistic() {
System.out.println("StatisticByYearHandler");
}
}


其他的代码都不需要修改,再次查看Map中的值:

2.4.执行调用

随便写了一个测试方法,如下:

public void invoke() {
this.doInvoke("week");
this.doInvoke("month");
this.doInvoke("year");
}
public void doInvoke(String type) {
StatisticBaseHandler handler = select(type);
handler.doStatistic();
}

分别打印出了按周统计、按月统计、按年统计方法中的输出值,表示策略模式定义成功了,在我们实际的开放中,只需要前端(或其他调用端)传入对用的标识字符串,就可以执行不同的统计逻辑了。

3.总结

通过Spring获取接口的实现,并解析实现类上的注解的方式,可以在程序启动时动态的将策略注入到一个Map中,作为策略的容器。使用时传入标识符就可以获取到对应的策略执行了。

相关推荐

Java框架 —— Spring简介

简介一般来说,Spring指的是SpringFramework,它提供了很多功能,例如:控制反转(IOC)、依赖注入(DI)、切面编程(AOP)、事务管理(TX)主要jar包org.sprin...

Monkey自动化测试

Monkey1.通过Monkey程序模拟用户触摸屏幕、滑动Trackball、按键等操作来对设备上的程序进行压力测试,检测程序多久的时间会发生异常;2.Monkey主要用于Android的压力...

十年之重修SpringBoot启动&amp;自动装载&amp;Bean加载过程

总结Springboot的自动装载,完全是依赖Bean的自动注册,其中默认的规则,是把需要自动装载的bean全名称编辑在spring.factories(2.7之后的版本,还支持.imports文件)...

一些可以显著提高大型 Java 项目启动速度的尝试

我们线上的业务jar包基本上普遍比较庞大,动不动一个jar包上百M,启动时间在分钟级,拖慢了我们在故障时快速扩容的响应。于是做了一些分析,看看Java程序启动慢到底慢在哪里,如何去优化,...

class 增量发包改造为 jar 包方式发布

大纲class增量发包介绍项目目录结构介绍jar包方式发布落地方案class增量发包介绍当前项目的迭代修复都是通过class增量包来发版本的将改动的代码class增量打包,如下图cla...

Flink架构及其工作原理(很详细)

原文链接:https://www.cnblogs.com/code2one/p/10123112.html关键词:Flink架构、面试杀手锏!更多大数据架构、实战经验,欢迎关注【大数据与机器学习】,...

大促系统优化之应用启动速度优化实践

作者:京东零售宋维飞一、前言本文记录了在大促前针对SpringBoot应用启动速度过慢而采取的优化方案,主要介绍了如何定位启动速度慢的阻塞点,以及如何解决这些问题。希望可以帮助大家了解如何定位该类问...

Maven工程如何使用非Maven仓库jar包

使用Maven之前,一直都是自己手工在网上搜索需要的jar包,然后添加到工程中。以这样的方式开发,工作了好多年,曾经以为以后也会一直这样下去。直到碰上Maven,用了第一次,就抛弃老方法了。Maven...

【推荐】一款开源免费、功能强大的短链接生成平台

项目介绍reduce是一款开源免费、功能强大的短链接生成平台。部署在服务器,使用短域名解析即可提供服务。CoodyFramework首秀,自写IOC、MVC、ORM、TASK、JSON、DB连接池、...

K8S官方java客户端之七:patch操作

欢迎访问我的GitHubhttps://github.com/zq2599/blog_demos内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;...

Java 的业务逻辑验证框架 之-fluent-validator

开发人员在维护核心业务逻辑的同时,还需要为输入做严格的校验。当输入不合法时,能够给caller一个明确的反馈,最常见的反馈就是返回封装了result的对象或者抛出exception。一些常见...

互联网大厂后端必看!手把手教你替换 Spring Boot 中的日志框架

在互联网大厂的后端开发工作中,SpringBoot框架是搭建项目的“得力助手”,使用十分普遍。但不少开发者都遇到过这样的困扰:SpringBoot默认集成的Logback日志框架,在实际...

测试经理教你如何用monkey进行压力测试!

一、monkey是什么1、monkey程序由android系统自带,使用Java语言写成,在Android文件系统中的存放路径是:/system/framework/monkey.jar2、Mo...

Java-Maven详解

一、什么是Maven?ApacheMaven是一个软件项目管理的综合工具。基于项目对象模型(POM)的概念,提供了帮助管理构建、文档、报告、依赖、发布等方法,Maven简化和标准化项目建设过程。处理...

SpringBoot打包部署最佳实践

springboot介绍SpringBoot目前流行的javaweb应用开发框架,相比传统的spring开发,springboot极大简化了配置,并且遵守约定优于配置的原则即使0配置也能正常运...

取消回复欢迎 发表评论: