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

行为型模式(一)策略模式

目录

1. 介绍

2. 目的

3. 实践


1. 介绍

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,将每种算法封装成具体的策略类,并使它们可以互相替换。策略模式使得算法可以独立于客户端而变化,客户端可以在运行时动态地选择不同的策略来执行相应的算法。

在策略模式中,通常包括以下几个角色:

  1. Context(上下文): 上下文类持有一个策略对象的引用,它将客户端请求委派给具体的策略对象来执行相应的算法。上下文类通常包含一个可以动态切换策略的方法,以便在运行时选择不同的策略。
  2. Strategy(策略): 策略接口或抽象类定义了一个算法族,其中每个具体的策略类实现了这个接口或继承了这个抽象类。策略类封装了具体的算法实现,客户端通过上下文类调用策略对象的方法来执行算法。

  3. ConcreteStrategy(具体策略): 具体策略类实现了策略接口或抽象类,它包含了具体的算法实现。每个具体策略类实现了一种特定的算法,可以根据具体需求选择不同的具体策略类来执行相应的算法。

 策略模式的核心思想是将算法的实现和使用分离,使得算法可以独立变化而不影响客户端代码。通过策略模式,可以更好地组织和管理复杂的算法逻辑,提高代码的灵活性、可维护性和可扩展性。策略模式常用于需要动态地切换算法或根据不同条件选择不同算法的场景。

2. 目的

  • 消除大量的条件判断语句: 当代码中存在大量的if-else语句用于根据不同条件执行不同的逻辑时,策略模式可以帮助将不同的条件逻辑封装在不同的策略类中,从而避免代码臃肿和难以维护。
  • 提高代码的灵活性和可扩展性: 策略模式使得具体的策略类可以独立变化,客户端可以在运行时动态地选择不同的策略对象,从而实现系统的灵活性和可扩展性。

  • 避免代码重复: 将公共部分抽象到策略接口中,具体策略类只需实现自己特有的部分。

  • 提高代码的可读性和可维护性: 策略模式将算法的实现细节隐藏在具体策略类中,使得代码结构更清晰,易于理解和维护。

总的来说,策略模式可以帮助解决多个条件判断导致的代码复杂性、提高代码的灵活性和可扩展性,以及避免代码重复,从而提高代码质量和可维护性。

3. 实践

医嘱打印功能,多个打印模板,后续还会增加模板。

针对不同打印模板,进行不同数据处理。

使用策略模式就能很好解决此类问题。

//策略接口
public interface IPrintMethod {List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO);default Map<String, List<BiOrderPrint>> toMap(List<BiOrderPrint> list) {return list.stream().collect(Collectors.groupingBy(BiOrderPrint::getFyFlag));}default List<BiOrderPrint> toList(Map<String, List<BiOrderPrint>> map) {return map.values().stream().flatMap(List::stream).collect(Collectors.toList());}
}//策略实现类1
@Component
@RequiredArgsConstructor
public class PqMethod implements IPrintMethod {private final HandlerOne handlerOne;private final HandlerTwo handlerTwo;private final HandlerThree handlerThree;private final HandlerFour handlerFour;private final HandlerFive handlerFive;private final HandlerLast handlerLast;@Overridepublic List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO) {//1. 数据转换,数据预处理List<BiOrderPrint> biOrderPrintList = handlerOne.doHandler(bo);Map<String, List<BiOrderPrint>> map1 = toMap(biOrderPrintList);//2. 数据填充Map<String, List<BiOrderPrint>> map2 = handlerTwo.doHandler(map1);//3. 根据每页条数,分割部分Map<String, List<BiOrderPrint>> map3 = handlerThree.doHandler(map2, dicItemDTO);//4. 每个分页里面的数据均是小于等于n的,将数据补 全Map<String, List<BiOrderPrint>> map4 = handlerFour.doHandler(map3, dicItemDTO);List<BiOrderPrint> resultList = toList(map4);// 5. 处理特殊数据handlerFive.doHandler(bo);// 6. 报存return handlerLast.doHandler(resultList);}
}//策略实现类2
@Component
@RequiredArgsConstructor
public class SyMethod implements IPrintMethod {private final HandlerOne handlerOne;private final HandlerTwo handlerTwo;private final HandlerLast handlerLast;@Overridepublic List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO) {// 1. 数据转换List<BiOrderPrint> biOrderPrintList = handlerOne.doHandler(bo);// 2. 过滤相同orderId的数据,只保留一份List<BiOrderPrint> list1 = new ArrayList<>(biOrderPrintList.stream().collect(Collectors.toMap(BiOrderPrint::getOrderId,Function.identity(),(existing, replacement) -> existing)).values());// 3. 数据填充Map<String, List<BiOrderPrint>> map1 = toMap(list1);Map<String, List<BiOrderPrint>> map2 = handlerTwo.doHandler(map1);List<BiOrderPrint> resultList = toList(map2);// 4. 报存return handlerLast.doHandler(resultList);}
}//......
//Context(上下文)
@Service
@RequiredArgsConstructor
public class OrderPrintContext {private final List<IPrintMethod> IPrintMethods;public List<BiOrderPrint> doPrint(BiOrderPrintSaveBO bo, SysDicItemDTO dicItemDTO) {//将所有策略实现类放到map里,前端传具体策略Map<String, IPrintMethod> printMethodMap = IPrintMethods.stream().collect(Collectors.toMap(IPrintMethod -> IPrintMethod.getClass().getSimpleName(), Function.identity()));if (ObjectUtil.isNull(dicItemDTO)) {throw new ServiceException(OrderErrorEnum.ERROR_82003, bo.getBillType());}IPrintMethod IPrintMethod = printMethodMap.get(dicItemDTO.getValue3());return IPrintMethod.doPrint(bo, dicItemDTO);}
}

相关文章:

行为型模式(一)策略模式

目录 1. 介绍 2. 目的 3. 实践 1. 介绍 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一系列算法&#xff0c;将每种算法封装成具体的策略类&#xff0c;并使它们可以互相替换。策略模式使得算法可以独立于客户端而变化&#x…...

JAVA中的Wrapper类

ava中的Wrapper类&#xff0c;也称为包装类&#xff0c;是Java提供的一组特殊类&#xff0c;它们将基本数据类型&#xff08;如int、char、double等&#xff09;封装为对象。这种封装提供了基本数据类型所不具备的功能&#xff0c;如类型转换、序列化、以及在集合&#xff08;如…...

在没有硬盘的情况下进行电脑数据迁移

电脑数据迁移方式 在更换电脑的时候需要进行文件的传输&#xff0c;但是没有硬盘可以选择使用网线直连或者无线文件共享。通用配置 1.将旧电脑的文件夹或者磁盘设置文件共享 找到指定的文件夹右键属》属性&#xff0c;点击共享》点击高级共享 选择共享文件夹以及修改共享用户…...

C++转Java基础知识

目录 1. Java基础知识 1.1 JDK和JVM 1.2 Java基础代码演示 1.3 Java中的注释 1.4 Java中的关键字 1.5 Java中的println和print的区别 2. Java中的数据类型 2.1 常量 2.2 标识符 2.3 变量 2.4 类型转换 2.5 自动类型转换 2.6 强制类型转换 3. 运算符 3.1 自增运算…...

搭建jenkins一键部署java项目

一、搭建jenkins 链接: https://pan.baidu.com/s/1jzx15PiyI8EhLd_vg7q8bw 提取码: ydhl 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 直接使用docker导入镜像&#xff0c;运行就好 docker run -di --name jenkins -p 8080:8080 -v /home/jenkins_home:/var/je…...

从零到一打造自己的大模型(一)模型实现

前言 最近看了很多大模型&#xff0c;也使用了很多大模型。对于大模型理论似乎很了解&#xff0c;但是好像又缺点什么&#xff0c;思来想去决定自己动手实现一个 toy 级别的模型&#xff0c;在实践中加深对大语言模型的理解。 在这个系列的文章中&#xff0c;我将通过亲手实践…...

【开源项目】基于RTP协议的H264码流发送器和接收器

RTP协议 1. 概述1.1 RTP协议1.2 RTP和UDP的关系 2. RTP打包H264码流2.1 RTP单一传输2.2 RTP分片传输2.3 RTP多片合入传输 3.工程3.1 头文件3.1.1 rtp.h3.1.2 utils.h 3.2 cpp文件3.2.1 rtp.cpp3.2.2 utils.cpp 4.测试5.小结 参考&#xff1a; 视音频数据处理入门&#xff1a;UD…...

【C++】4.类和对象(2)

文章目录 1.类的默认成员函数2.构造函数 1.类的默认成员函数 默认成员函数就是用户没有显式实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。一个类&#xff0c;我们不写的情况下编译器会默认生成以下6个默认成员函数&#xff0c;需要注意的是这6个中最重要的是前…...

搭建基于树莓派的Linux学习环境(TODO)

主要是想学一下Linux内核&#xff0c;所以搭一套环境&#xff0c;其实有几个选择&#xff0c;好几个都是我买了板子的。 首先是正点原子的RK3568&#xff0c;最早是想弄安卓&#xff0c;但是SDK的大小真的把我劝退了&#xff0c;动不动几百个G的空间&#xff0c;还有就是保底1…...

《大电机技术》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《大电机技术》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的第一批认定学术期刊。 问&#xff1a;《机电产品开发与创新》级别&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;哈尔滨电气集团公司 主办…...

Python 中使用 Split 忽略逗号

在 Python 中&#xff0c;split 方法可以用于将字符串分割成列表&#xff0c;默认情况下使用空格作为分隔符&#xff0c;但你也可以指定其他分隔符。若想使用 split 方法忽略逗号并按其他分隔符分割字符串&#xff0c;可以使用以下几种方法。 1、问题背景 在 Python 中&#x…...

YOLOv10改进 | 主干篇 | YOLOv10引入CVPR2023 顶会论文BiFormer用于主干修改

1. 使用之前用于注意力的BiFormer在这里用于主干修改。 YOLOv10改进 | 注意力篇 | YOLOv10引入BiFormer注意力机制 2. 核心代码 from collections import OrderedDict from functools import partial from typing import Optional, Union import torch import torch.nn as n…...

sql注入靶场搭建

1.安装小皮面板&#xff08;PhpStudy&#xff09; 1.从官网下载&#xff1a;http://www.xp.cn 2、Sqli-labs环境安装 准备好sqli-labs-php7-master文件 3.安装之前确保本地没有下载mysql服务器 如果电脑下载了MySQL可以把MySQL的服务停掉 此电脑>右键>管理>服务…...

【MySQL】MySQL的JSON特性

引言 MySQL从5.7版本开始引入了JSON数据类型&#xff0c;并在8.0版本中大大增强了JSON的支持&#xff0c;包括函数和索引功能。JSON数据类型允许你在MySQL表中存储JSON文档&#xff0c;这些文档可以是对象或数组&#xff0c;并且你可以使用SQL查询来检索、搜索、更新和修改这些…...

微信小程序 - 自定义计数器 - 优化(键盘输入校验)

微信小程序通过自定义组件&#xff0c;实现计数器值的增加、减少、清零、最大最小值限定、禁用等操作。通过按钮事件触发方式&#xff0c;更新计数器的值&#xff0c;并修改相关联的其它变量。通过提升用户体验&#xff0c;对计数器进行优化设计&#xff0c;使用户操作更加便捷…...

Nacos 容器化安装和代理配置指南

简介 Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;是阿里巴巴开源的一款动态服务发现、配置管理和服务管理平台。本文将介绍如何使用 Docker 容器化安装 Nacos 以及如何配置 Nacos 的代理。 前提条件 已安装 Docker 和 Docker Compose基本的 Doc…...

css水波浪动画效果

为缩小gif大小&#xff0c;动画效果做了加速&#xff0c;效果如下&#xff1a; <!DOCTYPE html> <html> <head> <style> *{padding:0;margin:0;}/*清除默认填充及边距*/.water{position:relative;width:100vw;height:100vh;overflow:hidden;background…...

SQL二次注入

目录 1.什么是二次注入&#xff1f; 2.二次注入过程 2.1寻找注入点 2.2注册admin#用户 2.3修改密码 1.什么是二次注入&#xff1f; 当用户提交的恶意数据被存入数据库后&#xff0c;因为被过滤函数过滤掉了&#xff0c;所以无法生效&#xff0c;但应用程序在从数据库中拿…...

深入学习小程序开发第二天:数据绑定与动态更新

一、概念 在小程序中,数据绑定是指将页面的数据和视图进行关联,使得数据的变化能够自动反映在视图上,而不需要手动操作DOM。这种绑定是双向的,即数据改变时视图更新,视图操作(如用户输入)也能改变数据。 二、用法 1.单向数据绑定与双向数据绑定: 在小程序中,数据绑定…...

【ai】 时间序列分析的python例子

时间序列分析 :分析和理解随时间变化的数据序列 在gcc的趋势滤波后,需要对排队延迟梯度进行检测及调整,参考的是一个阈值, 调整阈值时就使用了时间序列分析技术: 时间序列分析是统计学和数据分析中的一种技术,用于分析和理解随时间变化的数据序列。时间序列数据具有时间上…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...