【设计模式-我的思考】套餐模式

imom排故下线-订单状态集查询功能实现(套餐模式)

需求描述
排故下线状态
不排故:未启用排故下线确认配置&订单状态参数值!=(170、180、190)
待排故:启用排故下线确认配置&排故下线确认未执行&订单状态参数值!=(170、180、190)
已排故:启用排故下线确认配置&排故下线确认已执行&订单状态参数值!=(170、180、190)
已入库:订单状态参数值=170、180、190
每种状态的条件是与关系,状态集之间是或关系,多选则查询集合的并集.每个订单只属于其中一种状态集.
需要实现状态集查询,和结果集元素状态标记返回.

套餐模式

这是一种很常见的需求场景,就是对查询条件进行提前设置好套餐,根据用户选择的套餐,实现原本需要复杂配置的多个查询条件组合.

原来的查找条件分字段拆解给用户,用户需要各种条件组合才能看到自己想要的,BA通过对查询条件的组合抽象出来4个状态集合,每个集合包含一系列的字段组合查询,这样的交互模式为状态模式,将复杂留给开发,将便捷留给用户.
分析一下,原来的查询条件是自由组装的,现在在状态集的范围内,是个固定的参数值组合.很容易联想到状态模式来根据用户的选择实现条件的组合放入对象中初始化,选择多个状态则初始化多个对象放入对象集合进行循环查询,将结果集再进行组装.

于是做出如下设计:
在这里插入图片描述

关键代码

TroubleCheckStatus.java //套餐查询对象public void init(List<String> statusList){List<WipOrderInfoQO> queryQO=new List();//接收用户套餐选择,对子类对象进行初始化if(statusList ==null){WipOrderInfoQO object=new WipOrderInfoQO(this);queryQO.add(object);}else{for(String status:statusList){WipOrderInfoQO object=new WipOrderInfoQO(status,this);queryQO.add(object);}}this.queryList=queryQO;
}WipOrderInfoQO.java//原有查询对象public WipOrderInfoQO(TroubleCheckStatus object){//将父类的属性初始化到子类对象,实现传递
}public WipOrderInfoQO(String status,TroubleCheckStatus object){//status为套餐名称,可以从枚举或者spring bean中获取配置好的数据,对WipOrderInfoQO的属性进行定制化,套餐分解
}import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;import lombok.Getter;/*** className com.sany.mom.qm.troubleshooting.enums.TroubleCheckSetEnum 排故下线状态* 不排故:未启用排故下线确认配置&订单状态参数值!=(170、180、190) 待排故:启用排故下线确认配置&排故下线确认未执行&订单状态参数值!=(170、180、190)* 已排故:启用排故下线确认配置&排故下线确认已执行&订单状态参数值!=(170、180、190) 已入库:订单状态参数值=170、180、190** @author shengfq* @date 2024-10-15 11:32*/
@Getter
public enum TroubleCheckSetEnum {NONE("NONE", "不排故", false, false, onProgress()),TODO("TODO", "待排故", true, false, onProgress()),DONE("DONE", "已排故",  true, true, onProgress()),DONE1("DONE1", "已排故",  false, true, onProgress()),STOCKED("STOCKED", "已入库", null, null, stockedProgress());private static final Map<String, TroubleCheckSetEnum> STATUS_MAP = Arrays.stream(TroubleCheckSetEnum.values()).collect(Collectors.toMap(TroubleCheckSetEnum::getCode, Function.identity()));/*** 代码*/private String code;/*** 中文描述*/private String desc;/*** 是否启用排故下线确认配置*/private Boolean enable;/*** 排故下线确认状态*/private Boolean executed;/*** 订单状态子集合*/private List<Integer> progressStatus;TroubleCheckSetEnum(String code, String desc, Boolean enable, Boolean executed, List<Integer> progressStatus) {this.code = code;this.desc = desc;this.enable = enable;this.executed = executed;this.progressStatus = progressStatus;}/*** 非入库状态*/private static List<Integer> onProgress() {List<Integer> all= Arrays.stream(ProgressStatusEnum.values()).map(ProgressStatusEnum::getCode).collect(Collectors.toList());all.removeAll(stockedProgress());return all;}/*** 已入库:订单状态参数值=170、180、190*/private static List<Integer> stockedProgress() {return Arrays.asList(ProgressStatusEnum.DELETED.getCode(), ProgressStatusEnum.CLOSED.getCode(),ProgressStatusEnum.STORAGE.getCode());}/*** 根据code获取排故下线实例*/public static TroubleCheckSetEnum ofCode(String code) {return STATUS_MAP.get(code);}/*** 根据订单的相关配置信息来计算其排故下线状态实例** @param enable 订单类型是否启用排故下线* @param executed 订单是否执行了排故下线确认* @param progressStatus 订单状态*/public static TroubleCheckSetEnum getInstance(Boolean enable, Boolean executed, Integer progressStatus) {TroubleCheckSetEnum troubleCheckSetEnum= Arrays.stream(TroubleCheckSetEnum.values()).filter(i -> i.progressStatus.contains(progressStatus)).findAny().get();if(troubleCheckSetEnum==STOCKED){return troubleCheckSetEnum;}else{return Arrays.stream(TroubleCheckSetEnum.values()).filter(i -> i.progressStatus.contains(progressStatus) && i.enable.equals(enable) && i.executed.equals(executed)).findAny().get();}}
}

总结

在企业级应用开发中,查询条件是复杂的,如果能通过设置套餐来降低系统使用程度,这个产品设计原则就是很好的idea.技术上实现,则是在原有的查询上下文上增加一个状态集父类,通过初始化将套餐与枚举绑定,读取枚举配置好的配方参数对原有参数进行组合,代码侵入程度低,可扩展性强,耦合度低,实则是一个很不错的设计方案.
2024-10-22 晚

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

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

相关文章

Spire.PDF for .NET【页面设置】演示:在 C# 中应用 PDF 页面转换

当您在导出为 PDF 格式的文档中翻页时&#xff0c;页面过渡会显示装饰效果&#xff0c;例如溶解或擦除。当您以 PDF 格式创建幻灯片时&#xff0c;页面过渡特别有用。Spire.PDF是一款专为开发人员设计的强大 .NET 组件&#xff0c;可让您将页面过渡应用于 PDF 文件。 这里介绍…

vue3学习记录-组件通信

vue3学习记录-组件通信 1.父子组件通信2.兄弟组件传值2.1 以父组件为媒介2.2 发布订阅模式2.3 使用mitt2.3.1 全局使用2.3.2 局部使用 1.父子组件通信 父组件&#xff1a; <template>父组件原有的title:{{ title }}<p>---</p><com :title"title&qu…

MyBatis入门之一对一关联关系(示例)

【图书介绍】《SpringSpring MVCMyBatis从零开始学&#xff08;视频教学版&#xff09;&#xff08;第3版&#xff09;》-CSDN博客 《SpringSpring MVCMyBatis从零开始学(视频教学版)&#xff08;第3版&#xff09;》(杨章伟&#xff0c;刘祥淼)【摘要 书评 试读】- 京东图书 …

FreeRTOS实时操作系统(1)

前言&#xff1a;FreeRTOS内容较多&#xff0c;分篇发布&#xff0c;较为基础&#xff0c;旨在梳理知识&#xff0c;适合入门的同学 &#xff08;基于正点原子STM32F103开发板V2&#xff09; &#xff08;对于本篇&#xff0c;若有疑问&#xff0c;欢迎在评论区留言&#…

Wooden UI(木头UI纹理按钮边框 背景图标 带PNG素材)

资源包包含以下元素&#xff1a;按钮、图标、框架、复选框等&#xff0c;提供分层的 PSD 文件。 下载&#xff1a;​​Unity资源商店链接资源下载链接 效果图&#xff1a;

橡皮鸭调试法(Rubber Duck Debugging)

橡皮鸭调试法&#xff08;Rubber Duck Debugging&#xff09;是一种编程中的调试技巧&#xff0c;名字来源于一本书《The Pragmatic Programmer》&#xff0c;其中提到程序员可以把问题讲给一只橡皮鸭听&#xff0c;以便在讲解的过程中梳理思路并找到问题的根源。 基本原理&am…

微服务基础架构(图)

微服务基础架构是一种现代化的软件架构模式&#xff0c;旨在将大型复杂的应用程序拆分为多个小型、独立的服务。每个微服务专注于特定的业务功能&#xff0c;可独立开发、部署和扩展。 在微服务基础架构中&#xff0c;通常会使用轻量级的通信机制&#xff0c;如 RESTful API 或…

RISC-V笔记——RVWMO基本体

1. 前言 RISC-V使用的内存模型是RVWMO(RISC-V Weak Memory Ordering)&#xff0c;它是Release Consistency的扩展&#xff0c;因此&#xff0c;RVWMO的基本特性类似于RC模型。 2. RC模型 Release consistency(RC)的提出是基于一个观察&#xff1a;将所有同步操作用FENCE围在一…

升级Unity后产生的Objects内存泄露现象

1&#xff09;升级Unity后产生的Objects内存泄露现象 2&#xff09;能否使用OnDemandRendering API来显示帧率 3&#xff09;Unity闪退问题 4&#xff09;配置表堆内存如何优化 这是第405篇UWA技术知识分享的推送&#xff0c;精选了UWA社区的热门话题&#xff0c;涵盖了UWA问答…

PHP 8.1.0-dev后门远程命令执行漏洞

#简介 PHP verion 8.1.0-dev于2021年3月28日与后门一起发布&#xff0c;但是后门很快被发现并删除。 #漏洞概述 PHP verion 8.1.0-dev的PHP在服务器上运行&#xff0c;则攻击者可以通过发送User-Agentt标头执行任意代码。 #影响版本 PHP 8.1.0-dev #环境搭建 新建docker…

LLM之RAG实战(四十四)| rag-chatbot:支持Huggingface和Ollama任意模型的多PDF本地RAG方案

特点&#xff1a; 支持本地运行和Kaggle (new)运行支持Huggingface 和Ollama 的任意模型Process multiple PDF inputs.Chat with multiples languages (Coming soon).Simple UI with Gradio. 一、安装使用 1.1 Kaggle&#xff08;推荐&#xff09; Step1&#xff1a;把https…

Android 10.0 Camera2 拍照镜像功能实现

1.前言 在10.0的系统rom定制化开发中,在进行camera2的相关拍照功能开发中,在某些时候会遇到拍照照片 左右镜像的问题,就是照片左半边和右半边是反的,所以就需要在拍照的时候保存图片的时候实现 左右镜像功能,接下来就来分析下拍照保存图片的流程 2.Camera2 拍照镜像功能实…

SQL 干货 | SQL 反连接

最强大的 SQL 功能之一是 JOIN 操作&#xff0c;它提供了一种优雅而简单的方法&#xff0c;将一个表中的每一条记录与另一个表中的每一条记录结合起来。不过&#xff0c;有时我们可能想从一个表中找到另一个表中没有的值。正如我们将在今天的博客文章中看到的&#xff0c;通过包…

图片无损放大工具Topaz Gigapixel AI v7.4.4 绿色版

Topaz A.I. Gigapixel是这款功能齐全的图象无损变大运用&#xff0c;应用可将智能机拍摄的图象也可以有着专业相机的高质量大尺寸作用。你可以完美地放大你的小照片并大规模打印&#xff0c;它根本不会粘贴。它具有清晰的效果和完美的品质。 借助AIGigapixel&#xff0c;您可以…

[Linux网络编程]01-网络基础

此部分为《计算机网络》理论基础&#xff0c;可简要了解 一.计算机网络体系结构 常见的体系结构 OSI体系结构(法律上的国际标准)&#xff1a;物理层->数据链路层->网络层->运输层->会话层->表示层->应用层 TCP/IP体系结构(事实上的国际标准)&#xff1a;…

web网页QQ登录

代码&#xff1a; <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>QQ登录ent</title> </head> <style>ul > li{list-style: none; } a …

13.1 Linux_网络编程_TCP/UDP

字节序 1、概述 什么是字节序&#xff1a; 字节序就是字节的存储顺序&#xff0c;分为大端字节序和小端字节序。 大端字节序&#xff1a;低地址存高位&#xff08;网络&#xff09;小端字节序&#xff1a;低地址存低位&#xff08;主机&#xff09; 检验主机字节序模式&…

【Linux】-权限

&#x1f511;&#x1f511;博客主页&#xff1a;阿客不是客 &#x1f353;&#x1f353;系列专栏&#xff1a;深入代码世界&#xff0c;了解掌握 Linux 欢迎来到泊舟小课堂 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ​ 一、权限的概念 在Linux 中&…

开源图像超分ECBSR项目源码分析

相关介绍 项目GitHub地址&#xff1a;https://github.com/xindongzhang/ECBSR项目相关论文&#xff1a;https://www4.comp.polyu.edu.hk/~cslzhang/paper/MM21_ECBSR.pdf&#xff08;也可以点这里下载&#xff09;论文解读&#xff1a;Edge-oriented Convolution Block for Re…

秃姐学AI系列之:语义分割 + 数据集 | 转置卷积 + 代码

语义分割 语义分割将图片中的每个像素分类到对应的类别 通常来说现在的会议软件的背景虚化这个功能用的就是语义分割技术 无人车进行路面识别也是语义分割技术 语义分割 vs 实例分割 语义分割将图像划分为若干组成区域&#xff0c;这类问题的方法通常利用图像中像素之间的相关…