简单应用框架 VSEF 的架构
-
基本结构 = 入口 + 内核 + 依赖 内核 = 简单逻辑 + 复杂流程 简单逻辑 = 业务脚本 + 能力执行 复杂流程 = 流程编排 + 节点衔接 + 能力(任务)执行 -
演化 = 主题讨论 + 组件选取(市场组件优先)
▐ 入口
VSEF 观点:入口要清晰明确
就像 “要理清乱了的线团,就要找到线头一样”,将入口放在一个完整的目录,或者模块中的好处是:可以快速地功能总览,了解“提供哪些服务”、“接收那些消息”、“实现哪些任务”。
这里的目录类型有:
服务 service : 对外提供的 rpc 服务, 如HSF。这个一般会搭配一个服务 client 可调用者使用。
消息 message:可以再区分 metaq 和 notify 目录。
调度 scheduler:一些调度任务。
业务入口
▐ 内核
内核结构
-
流程 l3.process:进行业务活动编排,理解整个请求要完成什么事情。 -
活动 l4.activity:提供每个执行步骤的能力,代表了事情的关键节点。 -
能力(任务) l5.ability:节点执行时要做的一些具体任务,期望包装为能力,具备一定的复用性。
简单流程,主要是只读服务,如查询数据等,可以直接进入服务脚本 service。简单服务直接使用 l5能力(任务)。当逻辑逐渐复杂的时候,可以重构为复杂流程。
VSEF 观点:完成任务需要使用的资源都是依赖,依赖皆服务。服务都通过 l5能力 进行使用。
l5 能力在进行具体操作的时候,需要从数据、扩展、外调、中间件等渠道获取需要加工的数据,形成自己的理解。这个过程中,依赖的东西被称为“依赖”,通过“服务”的方式进行集成。
▐ 依赖
可以放进依赖的类型:
存储实现 repository : 数据库的读写操作。
中间件使用 middleware:包括缓存(tair)、发送消息(metaq、notify)、配置(diamond、switch)等。
网关实现 gateway:外部系统的调用,比如订单服务、退款服务等。
扩展实现 extension:业务差异性设计的扩展能力,需要业务提供扩展插件,或者平台代写。
VSEF 观点:基础设施是否易变,可自行判断,稳定时可以直接依赖。
这里值得讨论的是:如果基于六边形架构,这些基础设施被视为具体实现,应该通过抽象接口,依赖倒置的策略,实现解耦。但是实际在大家的系统中,可以判断其易变性,如果长期保持稳定的话,可以减少依赖抽象这一层,直接依赖基础设施,减少抽象成本,在思考层面做到 less is more。
VSEF 的目录只是一个初始化、相对简单的系统结构。如果随着业务的发展,各个组成部分会逐渐臃肿,系统风格可能也会变化。所以需要引入一些主题的讨论,结合业务情况进行一些设计,并选取相关组件,进行集成,形成有具体组织特征的、新特性的应用结构。
VSEF 观点:演化后的系统结构,结合了功能特性,才是各个组织的合适的系统结构。
注重平台服务的:关注平台逻辑和扩展机制。
注重组件表达的:与用户有交互,需要关注组件化协议。
注重领域协作的:需要关注协调者的模型和设计、应用内的领域划分逻辑。
注重数据服务的:关注数据能力性能、功能范围、数据模型映射。
VSEF 主题
▐ 组件协议
如果系统是平台型的,并且带界面表达,那么需要解决的就是各个端、各个页面、各个业务不一样的扩展能力。在内部模型和视图模型之间增加一层ViewModel, 然后基于这个进行各种转换,是不错的思路,比较典型的组件有:奥创、Astore等。
这里细化开来,关于 ViewModel 能够有多定制,有2个不同的走向:
转换主要在组件框架中:在核心逻辑之外,进行各种框架植入,如奥创、Astore, 在数据出口侧进行转换,转换的手段一般是基于规则表达式,利用相关反射能力进行数据组装。
转换主要在业务扩展中:不想在组件框架中承载过多代码,想和业务普通扩展逻辑走的近一些,在系统执行过程中的扩展逻辑中,植入视图的扩展,可以较好匹配前台组件。
奥创&DinamicX 方案运行原理
▐ 活动编排
流程编排是对一个业务操作执行过程进行进一步的划分,常见的编排组件有:Tbbpm、SmartEngine 等。但在实际开发过程中,常常会有这样的疑惑:为什么是这几个节点?为什么是这样的顺序?
为什么是这些节点?
-
是不是调用了一个服务?那么准备服务参数,调用,返回结果判断可以包装为一个节点。 -
是不是都在操作一个对象?那么这些操作可以归类为:初始化,修改,转换等内聚的方法。 -
是不是一些通用的处理?比如安全校验、日志监控、数据统计等。 -
是不是存在业务扩展性?可以单独独立出来,作为抽象方法,或者使用组合,提供相关接口定义。
-
为什么是这样的顺序
-
上下文数据依赖 -
本身地位:需要对最终结果进行收口,需要最后执行。 -
系统框架要求必须进行初始化先执行 -
其它等等
-
每个顶点出现且只出现一次 -
上一篇: 腾讯游戏内部正在使用该产品进行运维。
推荐阅读
-
通过 Node.js、Express 框架获取客户端 IP 地址,并获取 IP 对应的城市名称"????简单实用,收藏不丢
-
BSN 开放联盟链之旅 - 文昌链的技术、架构和应用介绍
-
堆栈打印跟踪活动启动过程(基于 Android 10.0.0-r41),修改框架以移除第三方应用程序的倒计时页面
-
Qt 模型视图代理对 QTableView 应用程序的简单介绍 - 二、设计思路
-
CS50:Django Notes - 创建一个简单的 Django Web 应用程序
-
35 岁实现财务*,腾讯程序员手握2300万提前退休?-1000万房产、1000万腾讯股票、加上300万的现金,一共2300万的财产。有网友算了一笔账,假设1000万的房产用于自住,剩下1300万资产按照平均税后20-50万不等进行计算,大约花上26-60年左右的时间才能赚到这笔钱。也就是说,普通人可能奋斗一辈子,才能赚到这笔钱。在很多人还在为中年危机而惶惶不可终日的时候,有的人的35岁,就已经安全着陆,试问哪个打工人不羡慕?但问题是有这样财富积累必然有像样的实力做靠山。没有人可以不劳而获。 看到这里,肯定有人说,那么对于普通人来说,卷可能真就成了唯一的出路。但是卷也有轻松的卷,“偷懒”的卷法,对于程序员而言,刨除掉一时无法改掉的开会传统占用的大部分时间,如何把有限的时间和精力放在真正重要的架构设计、需求设计上,而不是重复的造*,编码、改bug、手动测试。因此在科技改变生活的今天,学会使用AI工具成为程序员们的必备技能。 以全栈式全自动的软件开发工具飞算SoFlu软件机器人为例,作为全球首款面向微服务架构设计和最佳实践的软件机器人,SoFlu软件机器人改变了原来手工编码的作业模式,通过可视化拖拽方式以及参数配置就能实现等同于编写复杂代码的业务逻辑,在设计业务逻辑时就完成了微服务应用开发,做到“业务即图,图即代码”,实现“软件开发,十倍提效”。 而作为飞算SoFlu软件机器人的一个重要组成部分,FuncGPT(慧函数)支持所有类型函数创建。通过自然语言描述Java函数需求,实时生成高质量、高可读性的Java函数代码。生成代码可直接复制到IDEA,或一键导入Java全自动开发工具函数库。 FuncGPT(慧函数)具有五大核心能力: ● 自然语言:通过自然语言即可生成函数,降低软件开发门槛。 ● 秒级函数开发:全自动秒级开发函数,秒级完成,效率千倍提升。 ● 一站式函数开发应用:函数生成即可直接应用,效率、安全有保障。 ● 质量可靠:生成的函数代码符合业界规范、具备良好的可读性,符合最优解。 ● 灵活生成:可以根据开发人员的具体需求生成并支持调整和修改。 以“将文件流转换为File对象”这个需求为例,以下是FuncGPT(慧函数)秒级生成的代码: / 类名:FileConverter // 函数名:convertStreamToFile // 函数功能:将文件流转换为File对象 // POM依赖包:无 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; public class FileConverter { /** * 将文件流转换为File对象 * @param inputStream 文件流 * @param filePath 文件路径 * @param fileName 文件名 * @return 转换后的File对象 * @throws IOException 如果发生I/O异常 */ public static File convertStreamToFile(InputStream inputStream, String filePath, String fileName) throws IOException { File file = new File(filePath + File.separator + fileName); // 创建File对象 try (FileOutputStream outputStream = new FileOutputStream(file)) { // 创建文件输出流 byte buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { // 从文件流读取数据并写入文件 outputStream.write(buffer, 0, bytesRead); } } return file; // 返回转换后的File对象 } } // 函数示例 // 将文件流转换为File对象示例 // 入参:inputStream,文件流 // 入参:filePath,文件路径 // 入参:fileName,文件名 // 出参:file,转换后的File对象 // 调用示例: // InputStream inputStream = new FileInputStream("example.txt"); // String filePath = "C:\\Users\\User\\Documents"; // String fileName = "example.txt"; // File file = FileConverter.convertStreamToFile(inputStream, filePath, fileName); // System.out.println(file.getAbsolutePath); // 输出结果:例如,将文件流转换为File对象后,文件的绝对路径为:C:\Users\User\Documents\example.txt // 则输出结果为:C:\Users\User\Documents\example.txt 通过分析,不难发现以上代码:
-
太郎下一代架构揭秘 | GMTC《小程序跨框架开发的探索与实践》万言书
-
在闲鱼应用程序上发布二手物品的简单步骤
-
AVFoundation 框架分析(二十二)--源代码的简单视频流预览和播放示例(2)
-
Ubuntu 20.04 下的 Django 框架构建、部署、在线项目