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

设计模式学习笔记-----抽象策略模式

抽象策略模式由五个核心组件组成

策略接口

定义所有策略的统一规范,是策略模式的 "契约"

  • mark():策略的唯一标识(类似字典的 key),默认返回 null,需具体策略实现类重写(如InterviewSubjectHandler返回面试题类型标识)。
  • patternMatchMark():策略的模糊匹配标识(支持正则),用于复杂场景下的模式匹配(非必需实现)。
  • execute(REQUEST):无返回值的策略执行方法(默认空实现,按需重写)。
  • executeResp(REQUEST):有返回值的策略执行方法(默认返回 null,按需重写)。
/*** 策略执行抽象*/
public interface AbstractExecuteStrategy<REQUEST, RESPONSE> {/*** 执行策略标识*/default String mark() {return null;}/*** 执行策略范匹配标识*/default String patternMatchMark() {return null;}/*** 执行策略** @param requestParam 执行策略入参*/default void execute(REQUEST requestParam) {}/*** 执行策略,带返回值** @param requestParam 执行策略入参* @return 执行策略后返回值*/default RESPONSE executeResp(REQUEST requestParam) {return null;}
}

所有方法均为default(默认方法),允许策略实现类按需重写(无需实现所有方法),降低接口实现成本。

策略选择器

策略的 "管理者",负责策略的注册、查找和执行调度,是策略模式的核心上下文(Context)

  • 策略注册:实现ApplicationListener,在应用初始化时(onApplicationEvent)从 Spring 容器中获取所有AbstractExecuteStrategy实现类,存入abstractExecuteStrategyMap(key 为mark(),value 为策略实例),并校验mark唯一性(避免冲突)。
  • 策略查找choose()方法支持两种查找方式:
    • 精确匹配:通过mark直接从 map 中获取策略。
    • 模糊匹配:当predicateFlag=true时,用patternMatchMark()的正则匹配mark,适合多标识对应同一策略的场景。
  • 策略执行:提供chooseAndExecute()(无返回值)和chooseAndExecuteResp()(有返回值)方法,简化 "查找 + 执行" 的调用流程。
/*** 策略选择器*/
public class AbstractStrategyChoose implements ApplicationListener<ApplicationInitializingEvent> {/*** 执行策略集合*/private final Map<String, AbstractExecuteStrategy> abstractExecuteStrategyMap = new HashMap<>();/*** 根据 mark 查询具体策略** @param mark          策略标识* @param predicateFlag 匹配范解析标识* @return 实际执行策略*/public AbstractExecuteStrategy choose(String mark, Boolean predicateFlag) {if (predicateFlag != null && predicateFlag) {return abstractExecuteStrategyMap.values().stream().filter(each -> StringUtils.hasText(each.patternMatchMark())).filter(each -> Pattern.compile(each.patternMatchMark()).matcher(mark).matches()).findFirst().orElseThrow(() -> new ServiceException("策略未定义"));}return Optional.ofNullable(abstractExecuteStrategyMap.get(mark)).orElseThrow(() -> new ServiceException(String.format("[%s] 策略未定义", mark)));}/*** 根据 mark 查询具体策略并执行** @param mark         策略标识* @param requestParam 执行策略入参* @param <REQUEST>    执行策略入参范型*/public <REQUEST> void chooseAndExecute(String mark, REQUEST requestParam) {AbstractExecuteStrategy executeStrategy = choose(mark, null);executeStrategy.execute(requestParam);}/*** 根据 mark 查询具体策略并执行** @param mark          策略标识* @param requestParam  执行策略入参* @param predicateFlag 匹配范解析标识* @param <REQUEST>     执行策略入参范型*/public <REQUEST> void chooseAndExecute(String mark, REQUEST requestParam, Boolean predicateFlag) {AbstractExecuteStrategy executeStrategy = choose(mark, predicateFlag);executeStrategy.execute(requestParam);}/*** 根据 mark 查询具体策略并执行,带返回结果** @param mark         策略标识* @param requestParam 执行策略入参* @param <REQUEST>    执行策略入参范型* @param <RESPONSE>   执行策略出参范型* @return*/public <REQUEST, RESPONSE> RESPONSE chooseAndExecuteResp(String mark, REQUEST requestParam) {AbstractExecuteStrategy executeStrategy = choose(mark, null);return (RESPONSE) executeStrategy.executeResp(requestParam);}@Overridepublic void onApplicationEvent(ApplicationInitializingEvent event) {Map<String, AbstractExecuteStrategy> actual = ApplicationContextHolder.getBeansOfType(AbstractExecuteStrategy.class);actual.forEach((beanName, bean) -> {AbstractExecuteStrategy beanExist = abstractExecuteStrategyMap.get(bean.mark());if (beanExist != null) {throw new ServiceException(String.format("[%s] Duplicate execution policy", bean.mark()));}abstractExecuteStrategyMap.put(bean.mark(), bean);});}
}

自动配置类

整合 Spring 容器,将策略选择器AbstractStrategyChoose注册为 Spring Bean,使其能被全局注入使用。通过 Spring 的自动配置机制,无需手动创建AbstractStrategyChoose实例,简化了策略模式的使用成本。

/*** 设计模式自动装配*/
@ImportAutoConfiguration(ApplicationBaseAutoConfiguration.class)
@Configuration
public class DesignPatternAutoConfiguration {/*** 策略模式选择器*/@Beanpublic AbstractStrategyChoose abstractStrategyChoose() {return new AbstractStrategyChoose();}}

策略模板类

作为策略的 "中间层",封装通用逻辑,避免具体策略类重复编码(结合了模板模式思想)。

通过抽象类提取共性逻辑,具体策略类只需关注自身特有的业务逻辑

@Component
public abstract class AbstractQuestionAddAndGetTemplate implements AbstractExecuteStrategy<QuestionInfoDTO, QuestionInfoVO> {@Resourceprivate QuestionInfoDao questionInfoDao;protected QuestionInfoVO buildQuestionInfoVO(QuestionInfoDTO questionInfoDTO) {QuestionInfo questionInfo = questionInfoDao.queryById(questionInfoDTO.getId());return QuestionInfoVO.builder().id(questionInfo.getId()).createdTime(questionInfo.getCreatedTime()).createdBy(questionInfo.getCreatedBy()).subjectDifficult(questionInfo.getSubjectDifficult()).subjectParse(questionInfo.getSubjectParse()).updateTime(questionInfo.getUpdateTime()).updateBy(questionInfo.getUpdateBy()).subjectType(questionInfo.getSubjectType()).subjectName(questionInfo.getSubjectName()).settleName(questionInfo.getSettleName()).build();}}

具体策略类

策略模式的 "具体实现者",负责特定场景的业务逻辑。

@Component
public class InterviewSubjectHandler extends AbstractQuestionAddAndGetTemplate {@Resourceprivate QuestionInterviewDao questionInterviewDao;@Overridepublic String mark() {return QuestionInfoTypeEnum.INTERVIEW.getDesc();}@Overridepublic void execute(QuestionInfoDTO requestParam) {QuestionInterview questionInterview = QuestionInterview.builder().subjectId(Math.toIntExact(requestParam.getId())).createdBy(requestParam.getCreatedBy()).subjectAnswer(requestParam.getSubjectAnswer()).isDeleted(IsDeletedFlagEnum.UN_DELETED.getCode()).createdTime(new Date()).updateTime(new Date()).build();questionInterviewDao.insert(questionInterview);}@Overridepublic QuestionInfoVO executeResp(QuestionInfoDTO requestParam) {QuestionInfoVO questionInfoVO = buildQuestionInfoVO(requestParam);QuestionInterview questionInterview = questionInterviewDao.queryById(requestParam.getId());questionInfoVO.setSubjectAnswer(questionInterview.getSubjectAnswer());return questionInfoVO;}}

执行流程

  • Spring 容器初始化时,AbstractStrategyChoose监听ApplicationInitializingEvent事件。
  • 从容器中扫描到InterviewSubjectHandler(实现了AbstractExecuteStrategy),将其mark()(面试题标识)作为 key,实例作为 value,存入abstractExecuteStrategyMap
  • 当需要处理面试题时,调用AbstractStrategyChoose.chooseAndExecute("面试题标识", requestParam)
  • 选择器通过mark从 map 中找到InterviewSubjectHandler实例,调用其execute()方法执行新增逻辑。

总结

这套抽象策略模式通过接口定义规范选择器管理策略Spring 自动配置模板类复用逻辑的组合设计,实现了策略的 "定义 - 注册 - 选择 - 执行" 全流程自动化,既保证了业务逻辑的解耦,又提供了极高的扩展性和灵活性,非常适合业务场景多变、需要频繁新增策略的系统(如多类型题目处理场景)。

http://www.dtcms.com/a/351013.html

相关文章:

  • 【Ansible】Ansible部署K8s集群--准备环境--配置网络
  • 主流的 AI Agent 开发框架
  • 论文阅读(四)| 软件运行时配置研究综述
  • 游戏玩家批量多开挂机如何选择:云手机还是模拟器
  • LabVIEW 场效应晶体管仿真实验平台
  • 工业自动化系统架构-(多动子磁悬浮生产流水线 规划调度执行与协调)
  • 从下载到运行:MySQL 详细安装配置完整教程
  • 【Vue3】Cesium实现卫星及无人机轨迹跟踪
  • 大模型入门实战 | 基于 YOLO 数据集微调 Qwen2.5-VL-3B-Instruct 的目标检测任务
  • 数字IC前端设计——DC综合篇(生成filelist.f)
  • ADB 安装教程:如何在 Windows、 Linux 上安装 Android Debug Bridge
  • Java数据结构速成【1】
  • 项目设计文档——爬虫项目(爬取天气预报)
  • Qt——界面美化 QSS
  • 无人机三维路径规划首选算法:RRT_
  • 基于大模型的智能占卜系统实战-Qwen-VL、RAG、FastAPI
  • 【算法--链表题1】2. 两数相加:通俗详解
  • Linux系统网络管理学习.2
  • Spring面试题及详细答案 125道(26-45) -- Spring AOP篇
  • PLC通讯中遇到的实际场景
  • 8.25作业
  • 管家婆工贸ERP BB116.销售订单选存货
  • 视觉语言模型(VLM)
  • 动态带宽扩展(DBE):下一代Wi-Fi性能提升的关键技术
  • 《计算机视觉度量:从特征描述到深度学习》-- 大模型特征提取到特征检索
  • 身份管理与安全 (Protect identities)
  • 一文丝滑使用Markdown:从写作、绘图到转换为Word与PPT
  • HIDL的Car Audio架构简单梳理
  • Spark 节点 IDO 正式开启 —引领 PayFi 新时代
  • 解析蛋白质三维结构-Bio3D R包