参数映射服务完整解决方案

参数映射服务完整解决方案

1. 背景说明

在复杂的工作流程中,后续程序需要动态构造输入参数,这些参数源自多个前序程序的 JSON 数据输出。为了增强系统的灵活性和可扩展性,需要一个通用的参数映射服务来处理这种复杂的数据转换需求。

1.1 主要挑战

  • 数据来源多样性:需要处理来自不同程序的多种格式数据
  • 映射逻辑复杂:包含条件判断、循环处理、多源合并等场景
  • 配置驱动:需要通过配置文件定义映射规则,避免硬编码
  • 扩展性要求:支持新增映射类型,保持代码结构清晰

2. 核心需求

2.1 基础功能需求

  • 简单参数映射:支持从单一来源提取数据
  • 复杂逻辑支持
    • 条件逻辑(if-then-else)
    • 循环体处理
    • 字段映射和合并
  • 多来源支持:从多个前序程序提取数据,支持不同合并策略
  • 常量支持:允许直接使用固定值

2.2 设计目标

  • 通用性:提供统一的配置结构
  • 灵活性:支持多种动态逻辑
  • 易读性:配置结构清晰直观
  • 可扩展性:易于添加新的映射类型

3. 系统架构

3.1 架构图

+----------------+          +----------------+           +----------------+
| 前序程序输出     | ------> | 参数映射服务     | -------> | 后序程序输入参数    |
| JSON 数据       |          | (JSON 配置驱动) |           | 动态生成          |
+----------------+          +----------------+           +----------------+

3.2 核心组件

  1. 值对象基类:定义通用接口和基础功能
  2. 专用值对象:实现不同类型的参数映射逻辑
  3. 值对象工厂:负责创建具体的值对象实例
  4. 参数映射服务:统一的服务入口

4. 配置结构设计

4.1 参数配置

字段名称类型必填说明
namestring参数名称
valueobject参数值定义
descriptionstring参数描述

4.2 值对象类型

4.2.1 常量值(ConstantValue)
{"type": "constant","value": "固定值"
}
4.2.2 单一来源(SingleSourceValue)
{"type": "jmespath","jmespath": "data.path.to.value"
}
4.2.3 多来源(MultiSourceValue)
{"type": "multiSource","sources": {"sourceA": "path.to.arrayA","sourceB": "path.to.arrayB"},"mergeStrategy": "concat"
}
4.2.4 循环体(LoopValue)
{"type": "loop","jmespath": "items[*]","mappings": {"id": "id","name": "name"}
}
4.2.5 条件值(ConditionalValue)
{"type": "conditional","jmespath": "status","conditions": [{"if": "status == 'success'","then": {"type": "constant","value": "成功"}}],"else": {"type": "constant","value": "其他"}
}

5. 代码实现

5.1 工具函数

import jp from "jmespath";/*** 安全的 JMESPath 查询* @param {Object} data - 查询的上下文对象* @param {string} expression - JMESPath 表达式* @param {*} defaultValue - 查询失败时的默认值* @returns {*} 查询结果或默认值*/
function safeJMESPath(data, expression, defaultValue = null) {try {const result = jp.search(data, expression);return result !== undefined ? result : defaultValue;} catch (error) {console.warn(`JMESPath 查询失败: ${expression}`, error);return defaultValue;}
}

5.2 值对象基类

/*** 值对象基类*/
class ValueObject {constructor(config) {this.type = config.type;if (!this.type) {throw new Error("值对象类型未定义");}}getValue(context) {throw new Error("子类必须实现 getValue 方法");}
}

5.3 专用值对象实现

/*** 常量值对象*/
class ConstantValue extends ValueObject {constructor(config) {super(config);this.value = config.value;if (this.value === undefined) {throw new Error("常量值未指定");}}getValue() {return this.value;}
}/*** 单一来源值对象*/
class SingleSourceValue extends ValueObject {constructor(config) {super(config);this.jmespath = config.jmespath;if (!this.jmespath) {throw new Error("JMESPath 表达式未指定");}}getValue(context) {return safeJMESPath(context, this.jmespath);}
}/*** 多来源值对象*/
class MultiSourceValue extends ValueObject {constructor(config) {super(config);this.sources = config.sources;this.mergeStrategy = config.mergeStrategy || "concat";if (!this.sources || typeof this.sources !== "object") {throw new Error("多来源配置无效");}}getValue(context) {const values = Object.entries(this.sources).map(([key, jmespath]) => {return safeJMESPath(context[key], jmespath, []);});switch (this.mergeStrategy) {case "concat":return values.flat();case "unique":return [...new Set(values.flat())];case "priority":return values.find((value) => value.length > 0) || [];default:throw new Error(`不支持的合并策略: ${this.mergeStrategy}`);}}
}/*** 循环体值对象*/
class LoopValue extends ValueObject {constructor(config) {super(config);this.jmespath = config.jmespath;this.mappings = config.mappings || {};if (!this.jmespath) {throw new Error("循环体数据源表达式未指定");}}getValue(context) {const array = safeJMESPath(context, this.jmespath, []);if (!Array.isArray(array)) {return [];}return array.map((item) => {const mappedItem = {};for (const [key, expression] of Object.entries(this.mappings)) {mappedItem[key] = safeJMESPath(item, expression);}return mappedItem;});}
}/*** 条件值对象*/
class ConditionalValue extends ValueObject {constructor(config) {super(config);this.jmespath = config.jmespath;this.conditions = config.conditions || [];this.else = config.else;if (!this.jmespath) {throw new Error("条件数据源表达式未指定");}}getValue(context) {const data = safeJMESPath(context, this.jmespath, {});for (const condition of this.conditions) {if (safeJMESPath(data, condition.if, false)) {return new ValueObjectFactory().create(condition.then).getValue(context);}}return this.else ? new ValueObjectFactory().create(this.else).getValue(context) : null;}
}

5.4 值对象工厂

/*** 值对象工厂*/
class ValueObjectFactory {constructor() {this.typeMap = {constant: ConstantValue,jmespath: SingleSourceValue,multiSource: MultiSourceValue,loop: LoopValue,conditional: ConditionalValue,};}create(config) {const ValueObjectClass = this.typeMap[config.type];if (!ValueObjectClass) {throw new Error(`不支持的值对象类型: ${config.type}`);}return new ValueObjectClass(config);}
}

5.5 参数映射服务

/*** 参数映射服务*/
class ParameterMappingService {constructor(config) {this.parameters = config.parameters || [];this.factory = new ValueObjectFactory();}mapParameters(context) {const output = {};for (const param of this.parameters) {try {const valueObject = this.factory.create(param.value);output[param.name] = valueObject.getValue(context);} catch (error) {console.error(`处理参数 ${param.name} 时发生错误:`, error);output[param.name] = null;}}return output;}
}

6. 使用示例

// 配置示例
const config = {parameters: [{name: "version",value: {type: "constant",value: "1.0.0"}},{name: "userId",value: {type: "jmespath",jmespath: "userInfo.id"}},{name: "permissions",value: {type: "multiSource",sources: {rolePerms: "permissions[*].code",userPerms: "customPermissions[*]"},mergeStrategy: "unique"}}]
};// 示例数据
const context = {userInfo: {id: "user123"},rolePerms: {permissions: [{ code: "READ" },{ code: "WRITE" }]},userPerms: {customPermissions: ["ADMIN"]}
};// 使用示例
const service = new ParameterMappingService(config);
const result = service.mapParameters(context);
console.log(result);
/* 输出:
{version: "1.0.0",userId: "user123",permissions: ["READ", "WRITE", "ADMIN"]
}
*/

7. 总结

本解决方案通过灵活的配置结构和可扩展的代码设计,实现了一个通用的参数映射服务。主要特点:

  1. 配置驱动:通过 JSON 配置文件定义映射规则
  2. 类型丰富:支持常量、单源、多源、循环、条件等多种映射类型
  3. 扩展性好:基于工厂模式,易于添加新的值对象类型
  4. 健壮性强:完善的错误处理和默认值机制

后续优化方向

  1. 支持更多合并策略
  2. 添加参数验证功能
  3. 支持自定义函数扩展
  4. 增加缓存机制
  5. 添加映射性能监控

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

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

相关文章

SpringCloud - Nacos注册/配置中心

前言 该博客为Nacos学习笔记,主要目的是为了帮助后期快速复习使用 学习视频:7小快速通关SpringCloud 辅助文档:SpringCloud快速通关 一、简介 Nacos官网:https://nacos.io/docs/next/quickstart/quick-start/ Nacos /nɑ:kəʊ…

IDEA安装离线插件(目前提供了MavenHelper安装包)

目录 1、离线安装方式2、Maven Helper 1、离线安装方式 首先访问 IDEA插件网站 下载离线插件安装包,操作如下: 然后打开IDEA的Settings配置,点击Plugins,点击右侧设置按钮(齿轮),选择Install P…

科技赋能数字内容体验的核心技术探索

内容概要 在数字化时代,科技的迅猛发展为我们的生活和工作带来了深刻的变革。数字内容体验已经成为人们获取信息和娱乐的重要途径,而这背后的技术支持则扮演着至关重要的角色。尤其是在人工智能、虚拟现实和区块链等新兴技术的推动下,数字内…

【LeetCode 刷题】贪心算法(2)-进阶

此博客为《代码随想录》贪心算法章节的学习笔记,主要内容为贪心算法进阶的相关题目解析。 文章目录 135. 分发糖果406. 根据身高重建队列134. 加油站968. 监控二叉树 135. 分发糖果 题目链接 class Solution:def candy(self, ratings: List[int]) -> int:n l…

工业相机,镜头的选型及实战

工业相机和镜头的选型是机器视觉系统中的关键步骤,选型不当可能导致成像质量差或系统性能不达标。(用于个人的学习和记录) 一、工业相机选型方法 确定分辨率 分辨率需求:根据被测物体的尺寸和检测精度要求计算所需分辨率。 公式…

探索robots.txt:网站管理者的搜索引擎指南

在数字时代,网站如同企业的在线名片,其内容和结构对搜索引擎的可见性至关重要。而在这背后,有一个默默工作的文件——robots.txt,它扮演着搜索引擎与网站之间沟通桥梁的角色。本文将深入探讨robots.txt的功能、编写方法及其在现代…

使用WebUI访问本地Deepseek(Ollama集成Open WebUI)

在《deepseek本地部署和使用(Linux虚拟机)》中,我们使用Ollama部署了Deepseek-r1,但是只能通过命令行方式交互,默认Ollama启动后,会启动一个监听到127.0.0.1,用以接收POST 请求,服务…

windows蓝牙驱动开发-蓝牙 LE 邻近感应配置文件

邻近感应检测是蓝牙低功耗 (LE) 的常见用途。 本部分提供了创建可用于开发 UWP 设备应用的邻近感应配置文件的设备实现的指南。 在开发此应用之前,应熟悉蓝牙 LE 函数和蓝牙 LE 邻近感应配置文件规范。 示例服务声明 蓝牙低功耗引入了一个新的物理层,…

模型 冗余系统(系统科学)

系列文章分享模型,了解更多👉 模型_思维模型目录。为防故障、保运行的备份机制。 1 冗余系统的应用 1.1 冗余系统在企业管理中的应用-金融行业信息安全的二倍冗余技术 在金融行业,信息安全是保障业务连续性和客户资产安全的关键。随着数字化…

AI绘画社区:解锁艺术共创的无限可能(9/10)

AI 绘画:不只是技术,更是社交新潮流 在科技飞速发展的今天,AI 绘画早已不再仅仅是一项孤立的技术,它正以惊人的速度融入我们的社交生活,成为艺术爱好者们交流互动的全新方式,构建起一个充满活力与创意的社…

DeepSeek使用技巧大全(含本地部署教程)

在人工智能技术日新月异的今天,DeepSeek 作为一款极具创新性和实用性的 AI,在众多同类产品中崭露头角,凭借其卓越的性能和丰富的功能,吸引了大量用户的关注。 DeepSeek 是一款由国内顶尖团队研发的人工智能,它基于先进…

IDEA - 一个启动类多次启动方法

More Run/Debug -> Modify Run Configuration -> modify options -> Allow mutiple instances

Android Studio 配置 Gerrit Code Review

很多大厂(华为、荣耀)的大型项目都有gerrit代码审查流程,那么我们如何实现不手动敲命令行,就在Android Studio中像平常开发一样,只需要用鼠标点点点,就能将代码推送到gerrit审查仓呢,现在就来跟…

TypeScript 中的对象类型:深入理解接口和类型别名

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【Java基础】序列化、反序列化和不可变类

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:Java基础面经 📚本系列文章为个…

吴恩达深度学习——卷积神经网络的特殊应用

内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习使用。 文章目录 人脸识别相关定义Similarity函数使用Siamese网络实现函数d使用Triplet损失学习参数 神经风格迁移深度卷积网络可视化神经风格迁移的代价函数内容损失函数风格损失函数 人脸识别 …

搭建linux qt5.6环境

文章目录 准备工作步骤测试 准备工作 1、linux虚拟机环境 2、linux qt安装包相关文件,本文采用压缩包方式 步骤 1)启动虚拟机并登入 2)打开linux终端命令行,ifconfig获取当前linux环境的ip 3)使用WinSCP设置好ip、…

C++ 使用CURL开源库实现Http/Https的get/post请求进行字串和文件传输

CURL开源库介绍 CURL 是一个功能强大的开源库,用于在各种平台上进行网络数据传输。它支持众多的网络协议,像 HTTP、HTTPS、FTP、SMTP 等,能让开发者方便地在程序里实现与远程服务器的通信。 CURL 可以在 Windows、Linux、macOS 等多种操作系…

【产品小白】用户调研的需求是否都采纳?

在用户调研中,并非所有需求都应被直接采纳,而应通过系统分析转化为符合产品战略的有效决策。以下是关键思考框架: 1. 用户需求 ≠ 产品需求 矛盾性:用户个体需求可能相互冲突(如A功能的去留),需…

如何导入第三方sdk | 引入第三方jar 包

0. 背景1. 上传私有仓库2. 使用本地文件系统 0. 背景 对接一些第三方功能,会拿到第三方的sdk,也就是jar包,如何导入呢 1. 上传私有仓库 最好的方式就是将第三方jar包,上传到私有的仓库,这样直接正常在pom引用即可如果只…