软件架构生态化-多角色交付的探索实践
作为一个技术架构师,不仅仅要紧跟行业技术趋势,还要结合研发团队现状及痛点,探索新的交付方案。在日常中,你是否遇到如下问题 “ 业务需求排期长研发是瓶颈;非研发角色感受不到研发技改提效的变化;引入ISV 团队又担心质量和安全,培训周期长“等等,基于此我们探索了一种新的技术体系及交付方案来解决如上问题。
背景
嗨,大家都知道软件研发需要许多角色共同协作,包括客户、产品经理、研发工程师、测试人员、实施运营团队等等。在这众多角色中,研发工程师的人数占比最高,但是研发资源毕竟有限,随着需求量不断增加,在项目中还会听到如下吐槽:
1、研发团队排期瓶颈,非研发角色感受不到研发技改提效的变化。
2、引入ISV 团队又担心质量和安全问题,而且培训成本高、周期长,在核心复杂系统中,不敢也无法短时间大规模引入。
不过,如果有一种方法能够实现生态化交付和全民开发的愿景,那就可以解决上述问题了!这种方法可以让所有角色,无论是技术还是非技术的,以安全、更简单的方式参与进来。
这样一来,就可以在不增加团队人数的情况下,提高团队的吞吐量,实现更高效的需求交付,是不是很奇妙呢?
挑战
为了达到生态化交付和全民开发的愿景,我们需要解决如下几个问题?
1、如何让非技术角色实现研发的交付?
2、如何让全民开发者完整实现一个需求闭环,而非仅仅实现其中一部分需求?
3、如何解决交付中核心系统安全问题?
我们带这几个问题看下解决方案。在讲技术方案之前,我们先站在客户角度,从整体看一下,一个系统的需求都来自哪里?而我们都知道比起从0-1新做一个系统,二次扩展类需求更加复杂,我们今天就以二次扩展类需求入手和大家一起分享下,在京东智能供应链Y做的一些实践。
方案
设计思路
如上图就是任意一个系统中二次扩展类需求分类的最大集合,主要有8类:API类、参数类、模版类,界面类、流程类、规则类及数据库类。
1、API类:主要是新增API和在原有API的扩展,例如,原有API上新增一些属性。
2、模版类:主要是新增一个模版。例如,制作一类新的合同模版或问卷调研,各部门填报填写。
3、参数类:主要是新增KV类的参数。例如,新增“是否包括自营商品“参数,并让这些参数在某些逻辑中起到作用。
4、UI类:主要是新增菜单、按钮、布局、图表、校验规则等。例如新增一个外呼按钮,并调用外呼系统 接口。
5、流程类:在原有流程节点中新增新的节点。
6、规则类:在原有的规则前、后等,新增新的规则。
7、数据库类:在原有表中增加新的属性,或者新增一个子表。
8、最后还有一类其他:无法划分为某一类,需要复杂的逻辑处理实现。例如 数据重新聚合与逻辑运算
我们就基于这些研发的需求类型,设计一套技术体系,实现生态化交付和全民开发的愿景。
技术方案
我们把软件系统分成三层,建立完整的全链路扩展技术体系,在把这些能力通过零低代码手段把他们进行打通、包装和开放,就可以实现屏蔽源代码的情况下,对系统进行安全、简单、闭环的二次增强,进而达到全民开发的目标。具体包括:
1、界面层:该层扩展主要手段就是零低代码技术。
2、接口层:该层扩展主要手段就是依靠不同模型之前的映射来解决,而模型的扩展就可以依靠对象扩展来解决。
3、服务层:该层扩展主要依靠流程、规则引擎来实现,这个业界有很多开源工具,例如activity和drools等。另外还有很多场景是复杂的逻辑变更,这个可以依靠插件、事件驱动模式来实现。
4、模型层:该层扩展主要手段就是依靠元数据驱动,通过依赖元数据对象,而非底层物理数据库。
以上能力,在通过最后零代码技术的加持和封装,实现可视化配置,形成一个工作空间,在对工作空间进行分角色授权,让不同角色以熟悉的语言进行操作,这样就可以实现生态化交付和全民开发的愿景。
所以说扩展的技术体系不是一个单一的解决方案,它需要零低代码、插件、业务事件、元数据驱动、流程规则引擎等技术共同协作才可以。而难点是这几个技术需要互相搭配好,实现扩展的互认,例如我们在对象模型扩展中增加了一个属性,这个属性需要在界面展示、需要在接口中透传、需要在规则中校验,这就需要做好顶层架构设计。
我们通过几个案例来描述,它需要和可以实现哪些能力?
案例
案例1:让非技术参与进来,体会技术提效的变化
需求描述:基于业务变化,一个核心系统,需新增 “渠道类型” 这个属性,改动涉及:
1、数据模型变化(技术上:数据库字段变化)
2、后端服务及规则变化(技术上:接口变化、对象变化、判断规则变化等)、
3、展现界面变化(技术上:UI 界面增加带数据权限的查询条件、表格新列及图表增加等),
也就是需要软件不同层次的进行变化。通常,这些特别技术的需求变更,只能技术排期做,但是通过这种新方式。产品经理/客户就可以在无需等待,7 分钟内,全程零代码的模式下完成。
1、在对象扩展中,增加新的属性。
2、在规则引擎中,基于新的属性,编排增加新的校验。
3、在界面扩展中,把在对象扩展中的新列拖拽出来,展示为查询条件,并制作一个新的饼状图展示到界面。
通过这个案例,也就是说我们可以把黑盒的研发工作,安全、高效的交付给其非研发角色自助完成,提升交付效率,减低沟通成本。另外还有一点值得一提,这种方式也让非技术人员,可以直观的感受到技术提效的变化。
案例2:不触及代码情况下,实现安全一站式开发
需求描述:基于业务变化,一个核心系统,需要与客服系统集成,实现对某类特殊业务的客服外呼,改动涉及:
1、新增一个外呼按钮
2、新增前端规则校验,只有履约数据滞留2天的才需要进行客服介入。
3、调用外呼接口,组装数据增加复杂逻辑并传递。
4、发送邮件通知相关角色。
同样,这些也是特别技术的需求变更,原来只能原厂技术开发来排期做,但是通过这种新方式。客户IT或ISV,就可以在不触及代码的情况下,通过统一平台一站式完成需求的变更。
1、在界面层中,通过零低代码手段完成按钮新增。
2、在界面层中,通过零低代码手段完成规则校验的新增。
3、在服务层中,通过插件方式,实现代码逻辑处理,并调用外呼接口。
4、在服务层中,通过事件订阅方式,监听外呼状态,配置邮件模版,实现邮件自动发送。
通过这个案例,我们可以看出来,业务需求具有多变性,不能仅仅依靠一种手段完成扩展,需要多种方式进行搭配,才能实现大幅度提效。
结束
其实零低代码、插件、业务事件、元数据驱动、流程规则引擎等技术在行业中并不是一个新事物,而这些技术可以互相搭配,实现完美集成和互认,让用户在一个平台针对不同业务的场景使用合适的技术,完成需求的自助化,是个难点。它不仅仅需要平台技术,还需要对业务系统需要合理的抽象、抽取。
最后,我们在回过头看看最开始的技术挑战。是不是都解决了呢?
1、如何让非技术角色实现研发的交付?答:通过零低代码模式进行封装和开放。
2、如何让全民开发者完整实现一个需求闭环,而非仅仅实现其中一部分需求?答:需要全链路开放和打通,并不仅局限一种技术手段。
3、如何解决交付中核心系统安全问题?答:屏蔽源代码的完整扩展体系。
相关文章:

软件架构生态化-多角色交付的探索实践
作为一个技术架构师,不仅仅要紧跟行业技术趋势,还要结合研发团队现状及痛点,探索新的交付方案。在日常中,你是否遇到如下问题 “ 业务需求排期长研发是瓶颈;非研发角色感受不到研发技改提效的变化;引入ISV …...

基于YOLOv5n/s/m不同参数量级模型开发构建茶叶嫩芽检测识别模型,使用pruning剪枝技术来对模型进行轻量化处理,探索不同剪枝水平下模型性能影响【续】
这里主要是前一篇博文的后续内容,简单回顾一下:本文选取了n/s/m三款不同量级的模型来依次构建训练模型,所有的参数保持同样的设置,之后探索在不同剪枝处理操作下的性能影响。 在上一篇博文中保持30的剪枝程度得到的效果还是比较理…...

深度解析 Llama 2 的资源汇总:不容错过
“ 探索 Llama 2 背后的过程,包括了模型的全面解析,在线体验,微调,部署等,这份资源汇总将带您深入了解其内涵。” 01 — 周二发布了文章《中文大模型 Chinese-LLaMA-Alpaca-2 开源且可以商用》后,不少朋友们…...

Git 删除 GitHub仓库的文件
新建文件夹 git bash here 在新建的文件夹里右键git bash here打开终端,并执行git init初始化仓库 git clone <你的地址> 找到github上要删除的仓库地址,并复制,在终端里输入git clone <你的地址> 要删除文件的库里右键git b…...

如何使用 ChatGPT 将文本转换为 PowerPoint 演示文稿
推荐:使用 NSDT场景编辑器 助你快速搭建可二次编辑的3D应用场景 步骤 1:将文本转换为幻灯片演示文稿 第一步涉及指示 ChatGPT 根据给定的文本生成具有特定数量幻灯片的演示文稿。首先,您必须向 ChatGPT 提供要转换的文本。 使用以下提示指示…...

html(七)meta标签
一 meta标签 1、背景:发现自带某些请求头2、本文没有实际的生产应用场景,仅仅作为技术积累 ① meta标签含义 1、metadata: 元数据,是用于描述数据的数据,它不会显示在页面上,但是机器却可以识别2、应用场景: [1]、SEO搜索引擎优化[2]、定义页面使用…...
《Go 语言第一课》课程学习笔记(五)
入口函数与包初始化:搞清 Go 程序的执行次序 main.main 函数:Go 应用的入口函数 Go 语言中有一个特殊的函数:main 包中的 main 函数,也就是 main.main,它是所有 Go 可执行程序的用户层执行逻辑的入口函数。 Go 程序在…...
Golang 并发编程基础
runtime 包,定义了协程管理相关的 API runtime.Gosched() package mainimport ("fmt""runtime" )func main() {go func() {for i : 0; i < 5; i {fmt.Println(i)}}()// 让出当前CPU给其他协程runtime.Gosched()fmt.Println("end...&qu…...

代码随想录算法训练营(二叉树总结篇)
一.二叉树的种类 1.满二叉树:就是说每一个非叶子节点的节点都有两个子节点。 2.完全二叉树:此二叉树只有最后一层可能没填满,并且存在的叶子节点都集中在左侧!!! (满二叉树也是完全二叉树&…...

华为开源自研AI框架昇思MindSpore应用案例:基于MindSpore框架的UNet-2D案例实现
目录 一、环境准备1.进入ModelArts官网2.使用CodeLab体验Notebook实例 二、环境准备与数据读取三、模型解析Transformer基本原理Attention模块 Transformer EncoderViT模型的输入整体构建ViT 四、模型训练与推理模型训练模型验证模型推理 近些年,随着基于自注意&…...

Python入门【TCP建立连接的三次握手、 TCP断开连接的四次挥手、套接字编程实战、 TCP编程的实现、TCP双向持续通信】(二十七)
👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误…...
React笔记-React入门
主要是现在要改一个开源项目,需要学习下React入门,在此记录一下。 几个关键的库 React底层核心:react.development.js React操作DOM库:react-dom.development.js 解析ES6语法:babel.min.js React.createElement() …...

SD WebUI 扩展:prompt-all-in-one
sd-webui-prompt-all-in-one 是一个基于 Stable Diffusion WebUI 的扩展,旨在提高提示词/反向提示词输入框的使用体验。它拥有更直观、强大的输入界面功能,它提供了自动翻译、历史记录和收藏等功能,它支持多种语言,满足不同用户的…...
Go和Java实现中介者模式
Go和Java实现中介者模式 下面通过一个同事之间相互通信的例子来说明中介者模式的使用。 1、中介者模式 中介者模式是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的 通信,并支持松耦合,使代码…...

CentOS系统环境搭建(十五)——CentOS安装Kibana
centos系统环境搭建专栏🔗点击跳转 关于Elasticsearch的安装请看CentOS系统环境搭建(十二)——CentOS7安装Elasticsearch。 CentOS安装Kibana 文章目录 CentOS安装Kibana1.下载2.上传3.解压4.修改kibana配置文件5.授予es用户权限6.kibana 后台…...

简单的洗牌算法
目录 前言 问题 代码展现及分析 poker类 game类 Text类 前言 洗牌算法为ArrayList具体使用的典例,可以很好的让我们快速熟系ArrayList的用法。如果你对ArrayList还不太了解除,推荐先看本博主的ArrayList的详解。 ArrayList的详解_WHabcwu的博客-CSD…...

vscode用ssh远程连接linux
1、vscode是利用ssh远程连接linux的,所以首先确保vscode已经安装了这两个插件 2、点击左下角的连接 3、选择Connect to Host…… 5、按格式输入 ssh 主机名ip 比如我的:ssh mnt192.168.198.128 6、选择第一个打开配置文件,确保输入正确 7、…...

chapter 3 Free electrons in solid - 3.2 量子自由电子理论对一些现象的解释
3.2 自由电子气的热容 Heat capacity of free electron gas 3.2.1 计算自由电子的热容 Calculation of Heat Capacity of free Electrons T>0K, total energy of free electrons: E ∫ E d N 3 5 N e E F 0 [ 1 5 12 π 2 ( k B T E F 0 ) 2 ] E \int EdN \frac{3}{5}…...
vue实现打印功能
在Vue应用中调用打印机功能,可以使用JavaScript的window.print()方法。这个方法会打开打印对话框,然后让我们选择打印设置并打印文档,但是尼这种方法依赖于浏览器的打印功能。 以下是一个简单的示例,演示如何在Vue组件中调用打印…...

golang—面试题大全
目录标题 sliceslice和array的区别slice扩容机制slice是否线程安全slice分配到栈上还是堆上扩容过程中是否重新写入go深拷贝发生在什么情况下?切片的深拷贝是怎么做的copy和左值进行初始化区别slice和map的区别 mapmap介绍map的key的类型map对象如何比较map的底层原…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

leetcode73-矩阵置零
leetcode 73 思路 记录 0 元素的位置:遍历整个矩阵,找出所有值为 0 的元素,并将它们的坐标记录在数组zeroPosition中置零操作:遍历记录的所有 0 元素位置,将每个位置对应的行和列的所有元素置为 0 具体步骤 初始化…...