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

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;刘祥淼)【摘要 书评 试读】- 京东图书 …

RK3576 安卓SDK编译环境搭建

编译 Android14 对机器的配置要求较高: 建议预留500G存储 多分配CPU和内存 建议使用 Ubuntu 20.04 操作系统或更高版本 sudo apt-get updatesudo apt-get install git gnupg flex bison gperf libsdl1.2-dev \ libesd-java libwxgtk3.0-dev squashfs-tools build-essential …

软考-软件设计师(11)-专题强化-算法设计与分析-算法特性、算法表示、算法时间复杂度、算法分类、C语言程序设计

场景 以下为高频考点、知识点汇总。 软件设计师上午选择题知识点、高频考点、口诀记忆技巧、经典题型汇总: 软考-软件设计师(1)-计算机基础知识点:进制转换、数据编码、内存编址、串并联可靠性、海明校验码、吞吐率、多媒体等: 软考-软件设计师(1)-计算机基础知识点:进制…

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…

CentOS 7 安装gcc编译环境

有时需要使用源码安装某个应用程序&#xff0c;有时还需要对源码进行一定程度的修改和定制才能满足业务需求&#xff0c;有时需要在linux环境下开发某个特定功能的c程序&#xff0c;此时都需要用到gcc编译环境&#xff0c;此时就需要安装gcc编译环境。 在 CentOS 7 上安装 C 编…

记一个mysql的坑

数据库表user&#xff0c; 存在一个name字段&#xff0c;字段为varchar类型 现在user表有这么两条记录: idnameageclass1NULL18一班2lisi20二班 假如我根据下面这一条件去更新&#xff0c;更新成功数据行显示为0 update user set age 19 where age 18 and class “一班”…

前端算法:字典and哈希表(力扣1题、349题解法)

目录 一、字典 1.概念 2.特点 3.在JS中如何实现 4.字典用法 使用对象作为字典 使用map 5.应用场景 二、哈希表 1.概念 2.工作原理 3. 在 JavaScript 中的实现 4.哈希表用法 使用 Map 作为哈希表 5.应用场景 三、字典与哈希表的区别 四、力扣算法实战 1.1题 两数…

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 拍照镜像功能实…

JDK17新特性,代码使用,作用详细讲解

目录 1.密封类和密封接口 作用 好处 1. 密封类 2. 密封接口 3. 非密封类 4. 抽象密封类 2.模式匹配for instanceof JDK17前的jdk版本 新JDK17 特性与优点 使用示例 注意事项 作用 3.文本块 作用 好处 代码实例 1. 基本语法&#xff1a; 2.换行和缩进&#xff1a; 3.包…

SQL 干货 | SQL 反连接

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

Vue中v-bind对样式控制的增强—(详解v-bind操作class以及操作style属性,附有案例+代码)

文章目录 v-bind对样式控制的增强2.1 操作class2.1.1 语法2.1.2 对象语法2.1.3 数组语法2.1.4 使用2.1.5 Test 2.2 操作style2.2.1 语法2.2.2 使用2.2.3 Test v-bind对样式控制的增强 2.1 操作class 2.1.1 语法 <div> :class "对象/数组">这是一个div&l…