从可逆计算看DSL的设计要点
低代码平台的可视化设计器本质上是DSL(Domain Specific Language)的结构化编辑器。可视化设计器将编辑的结果序列化成文本格式时所采用的规范就是一种DSL语法定义。
Nop平台基于可逆计算原理,提出了一整套系统化的构建机制来简化DSL的设计和实现,使得我们很容易增加针对自己业务领域的DSL,也很容易在已有DSL的基础上进行扩展。具体来说,Nop平台中所定义的DSL一般采用XML语法格式,符合所谓的XDSL规范要求。XDSL的设计要点如下:
一. DSL优先而不是可视化设计优先
很多低代码平台的设计重心是可视化设计器的简便易用,导致它的DSL格式设计随意、混乱冗长,不适合程序员人工阅读编写。XDSL强调DSL文本形式的设计应该简洁、直观,可以手工编写,也方便程序自动处理。可视化设计可以看作是文本形式DSL的另外一种形式的表象,可视化表象和文本形式之间可以按照规范化的规则进行可逆转换。
在这种设计思想下,同一个DSL可以具有多种可视化设计器,比如NopORM模型对应的DSL是app.orm.xml这种模型文件,而它的可视化设计器可以是Excel、PowerDesigner或者PDMiner。我们还可以增加更多的可视化设计器,只要它们的设计文件可以和orm.xml模型文件实现双向转换。
在具体的业务应用中,我们还可以增加采用定制化的可视化设计器,比如一个局部的细节设计器只负责设计模型文件的某个部分,然后通过差量合并运算将局部设计结果合并到整体模型中。
二. DSL的语法通过元模型来定义,而所有的DSL共享同样的元模型定义语言。
DSL的价值在于它所抽象出来的具有业务价值的领域语义空间,至于它采用什么样的语法形式本质上是一个次要问题。XDSL统一采用XML语法形式,这样就可以引入统一的XDefinition元模型语言来规范具体的DSL语法。
元模型是描述模型的模型。类似于元数据是描述数据的数据。
<orm x:schema="/nop/schema/orm/orm.xdef" xmlns:x="/nop/schema/xdsl.xdef">...
</orm>
-
在模型文件的根节点上,我们通过
x:schema
来指定元模型定义文件。 -
orm.xdef这个元模型使用xdef.xdef这个元元模型来定义。
-
xdef.xdef采用xdef.xdef自身来定义,所以我们不需要更高层次的元元元模型。
统一的元模型语言促进DSL之间的无缝嵌套
在Nop平台中,大量的DSL元模型定义中会引用已经定义的其他DSL模型。例如 api.xdef和xmeta.xdef都会引用已定义的schema.xdef
不同的DSL使用同样的类型定义,也便于复用同样的可视化设计组件、转换工具、校验规则等。
根据元模型自动提供IDE插件
Nop平台提供了一个IDEA插件nop-idea-plugin。它会根据x:schema
指定的元模型自动校验DSL语法,并实现自动语法提示,链接跳转等功能,对于函数类型的DSL节点,它还可以提供断点调试功能。当我们增加一个新的DSL语言的时候,不需要单独为它开发IDEA插件工具,直接就可以得到IDEA开发支持。
根据元模型,我们还可以自动推导得到可视化设计器。而不需要为每个DSL单独引入可视化设计器。
三. 所有DSL都需要提供分解、合并机制
一个DSL文件复杂到一定程度,必然需要引入分解、合并、库抽象等管理复杂性的机制。XDSL定义了一组标准化的Delta差量语法,具体参见xdsl.xdef
<meta x:extends="_NopAuthUser.xmeta" x:schema="/nop/schema/xmeta.xdef" xmlns:x="/nop/schema/xdsl.xdef" ><x:post-extends><biz-gen:GenDictLabelFields xpl:lib="/nop/core/xlib/biz-gen.xlib"/></x:post-extends>
</meta>
x:extends
用于继承已有的模型文件,而x:gen-extends
和x:post-extends
是内置的元编程机制(Meta Programming),它们用于实现可逆计算理论中的Generator部分,动态生成DSL模型对象,然后再进行Delta合并。
x:override
用于指定合并节点时所采用的合并策略,具体定义参见可逆计算理论中的Delta合并算法
四. 通过差量文件系统管理所有DSL文件
Nop平台将所有的模型文件纳入统一的虚拟文件系统来管理。这个虚拟文件系统提供了类似Docker技术中UnionFS文件系统的功能,内部不同的目录构成不同的层,高层目录中的文件会自动覆盖低层目录中的相同虚拟路径下的文件。
具体来说,/_vfs/_delta/default/a.xml
会自动覆盖/_vfs/a.xml
文件。在代码中所有使用虚拟文件路径/a.xml
的地方在运行时实际加载的文件是/_vfs/_delta/default/a.xml
文件。也就是说,我们不用修改原有的源代码,只需要在delta目录下增加同名的文件,就可以自动改变实际加载的模型内容。
- 可以通过配置项 nop.core.vfs.delta-layer-ids来指定多个delta层(缺省情况下只有一个default差量层)。
- 在delta目录下的XDSL文件可以通过
x:extends="super"
来表示继承前一个层中的模型文件。 - 可以将数据库表中保存的模型文件也映射到某个虚拟文件路径,比如wf:MyWf/1.0表示从数据库中的NopWfDefinition表中加载模型文件。
借助于差量文件系统以及XDSL内置的Delta合并算法,我们可以实现系统级别的Delta定制机制,在完全不修改基础产品源代码的情况下,通过增加Delta模块实现对系统的数据模型、业务逻辑、前端界面等进行深度的定制调整,参见如何在不修改基础产品源码的情况下实现定制化开发
五. 通过统一的Loader来加载DSL模型
Nop平台中使用统一的ResourceComponentManager来加载所有的DSL模型。
OrmModel model = (OrmModel)ResourceComponentManager.instance().loadComponentModel("/nop/auth/orm/app.orm.xml");
当我们增加一种新的DSL模型的时候,可以增加一个注册文件,例如orm.register-model.xml
<model x:schema="/nop/schema/register-model.xdef" xmlns:x="/nop/schema/xdsl.xdef"name="orm"><loaders><xlsx-loader fileType="orm.xlsx" impPath="/nop/orm/imp/orm.imp.xml"/><xdsl-loader fileType="orm.xml" schemaPath="/nop/schema/orm/orm.xdef"/></loaders>
</model>
通过这个注册模型,我们可以指定对于给定的文件类型,如何进行解析得到模型对象。
- xlsx-loader指定如何根据Excel导入模型配置解析Excel模型文件
- xdsl-loader指定DSL文件所必须具有的元模型,并按照元模型进行解析(模型文件的x:schema指定的元模型必须是schemaPath指定的值或者是在它基础上进行扩展的)
基于统一的模型加载器,我们可以实现针对任意模型的代码生成工具
java -jar nop-cli.jar gen abc.model.xlsx -t=/nop/templats/my-model
gen命令接受一个模型文件参数,然后通过-t参数来指定代码生成模板路径,就可以自动解析模型文件得到模型对象,传入到模板文件中生成代码。具体参见 数据驱动的差量化代码生成器
解析缓存和依赖追踪
ResourceComponentManager内部管理了所有DSL模型的解析缓存以及DSL模型文件之间的依赖关系。它的依赖追踪机制类似于前端Vue框架使用的依赖追踪,即动态记录模型解析过程中加载或者使用过的DSL模型,当模型文件的修改时间发生变化的时候,所有依赖它的模型缓存都自动被记为失效。
nop-cli工具还提供了watch功能,可以监听指定目录下为模型文件,当模型文件发生变化的时候自动重新执行代码生成器生成衍生的代码。
可逆计算的切入途径
可逆计算原理的核心实现全部被封装在ResourceComponentManager这个抽象之中。在第三方应用中引入可逆计算最简单的方式就是把自己的模型加载函数替换为ResourceComponentManager.loadComponentModel。比如说,为了给Spring和MyBatis框架引入模型文件的Delta定制功能,我们重新实现了beans.xml和mapper.xml的扫描功能,使用ResourceComponentManager来动态生成DOM对象,然后调用Spring和MyBatis的解析器去解析并注册到对应引擎中。
理论层面的分析可以参见从张量积看低代码平台的设计
六. 所有的DSL模型对象都支持扩展属性
XDSL模型对象的属性并不是在开发期固化的,它一般从AbstractComponentModel基类继承,支持增加任意的扩展属性。在具体的业务应用中,我们可以选择从已有的元模型继承,增加业务特定的扩展属性。
比如平台中内置了xmeta.xdef这个元模型。
我们可以定义xmeta-ext.xdef元模型,它从xmeta.xdef继承,然后增加一些扩展字段
<meta x:extends="/nop/schema/xmeta.xdef" xmlns:ui="ui" xmlns:graphql="graphql"x:schema="/nop/schema/xdef.xdef"xmlns:x="/nop/schema/xdsl.xdef" xmlns:xdef="/nop/schema/xdef.xdef"><props><prop ui:show="string" graphql:type="string" /></props></meta>
以上元模型表示为xmeta模型的prop节点增加ui:show属性和graphql:type属性。
然后在具体的meta文件中我们就可以使用xmeta-ext.xdef来替换原有的xmeta.xdef。
<meta x:schema="/my/schema/xmeta-ext.xdef">...</meta>
- IDEA插件会自动识别并使用扩展的元模型定义来校验Meta文件。
- 使用ResourceComponentManager.loadComponentModel加载的模型对象上会包含扩展属性。
也就是说,在不修改平台内置元模型定义的情况下,我们可以随时为已有的模型对象增加扩展属性,并在编程中像内置属性那样使用它们。
基于可逆计算理论设计的低代码平台NopPlatform已开源:
- gitee: canonical-entropy/nop-entropy
- github: entropy-cloud/nop-entropy
- 开发示例:docs/tutorial/tutorial.md
- 可逆计算原理和Nop平台介绍及答疑_哔哩哔哩_bilibili
相关文章:
从可逆计算看DSL的设计要点
低代码平台的可视化设计器本质上是DSL(Domain Specific Language)的结构化编辑器。可视化设计器将编辑的结果序列化成文本格式时所采用的规范就是一种DSL语法定义。 Nop平台基于可逆计算原理,提出了一整套系统化的构建机制来简化DSL的设计和…...
axios竟态问题
竟态问题 在我们日常开发经常遇到一些竟态问题 例子1 现象1 表格分页,如果设置请求loading, 先切换到分页第99页,迅速在又切换到第1页,最后列表显示的是第99页数据。 原因 由于第99页请求数据花费时间可能500ms,第1页数据只需要100ms,第1页…...

如何批量注册多个Outlook邮箱账号并避免关联
批量注册多个Outlook邮箱账号时,如何避免账号之间的关联性是一个重要的考量因素。会在此文一起探讨如何高效且安全地批量注册多个Outlook邮箱账号,并提供一些实用的建议来确保这些账号不会被关联。 一、Outlook邮箱批量注册机制 在深入注册流程之前&…...
如何在安卓設備上設置全局代理?
對於安卓用戶來說,設置全局代理是維護網路隱私一種有效的方法,可以幫助在所有應用中使用同一個代理伺服器。本文將詳細介紹如何在安卓設備上進行全局代理設置。全局代理指的是通過一個代理伺服器來轉發設備上所有應用程式的網路請求。這樣,所…...

操作系统实验记录
实验零:虚拟机安装 一、安装vmware虚拟机 与vmware匹配搜索结果 - 考拉软件 (rjctx.com),下载17.5.1版本即可下载后对照教程安装 二、下载iso虚拟驱动 搜索清华大学镜像网站,点击再搜ubuntu,下载这个4.1GB的iso文件安装后打开vmware虚拟机 三、配置vmware虚拟机 右键管…...
FastAPI 路径参数详解:动态路径与数据校验的灵活实现
FastAPI 路径参数详解:动态路径与数据校验的灵活实现 本文全面介绍了在 FastAPI 中使用路径参数的技巧和实现方式。路径参数允许 API 动态响应不同路径中的请求信息,结合 URL(Uniform Resource Locator)和 URI(Unifor…...

【STM32】SD卡
(一)常用卡的认识 在学习这个内容之前,作为生活小白的我对于SD卡、TF卡、SIM卡毫无了解,晕头转向。 SD卡:Secure Digital Card的英文缩写,直译就是“安全数字卡”。一般用于大一些的电子设备比如:电脑、数码相机、AV…...

我一口气记录下整个接口自动化测试过程!
一、为什么选用postman postman调试工具无论对于开发和测试小白,还是技术大牛来说应该都耳熟能详,在过去的几年里大家对这款工具应用最广的用途是把当作接口调试的测试工具,它能发送几乎所有类型的HTTP请求,操作界面非常简洁美观…...

【VS中Git同步提交 报错:访问.vs/FileContentIndex/xxx.vsidx权限不允许】
参考: Git commit vsidx file access denied in Visual Studio 一劳永逸的方法: 在VSCode里,Git->设置->选项:编辑.gitignore文件,如下图: 忽略整个.vs文件夹,再重新提交就不会有涉及…...

Linux下Nginx的安装与使用
Linux下Nginx的安装与使用 博客: www.lstar.icu 开源地址 Gitee 地址: https://gitee.com/lxwise/iris-blog_parent Github 地址: https://github.com/lxwise/iris-blog_parent 序言 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子…...
飞机布雷盖航程公式
飞机布雷盖航程公式 1. 喷气式飞机布雷盖航程公式推导2. 螺旋桨飞机布雷盖航程公式推导3. 喷气式飞机与螺旋桨飞机的差异分析3.1 喷气式飞机的推力产生机制3.2 螺旋桨推进推力产生机制 布雷盖航程公式(Breguet Range Equation)是描述飞行器巡航飞行阶段航…...
在K8s平台部署个人博客
在K8s平台部署个人博客 实验步骤查看wordpress前端的service浏览器访问http://node_ip:30090 实验步骤 kubectl create secret generic mysql-pass --from-literalpasswordYOUR_PASSWORD把mysql.tar.gz和wordpress.tar.gz上传到K8s工作节点,手动解压即可࿱…...
git入门教程10:git性能优化
一、配置优化 使用SSH协议: 相比HTTP/HTTPS协议,SSH协议在网络传输中更高效,且支持更安全的认证方式。确保你的远程仓库URL使用的是SSH协议,例如:git clone gitgithub.com:username/repo.git。 调整Git缓冲区大小&…...

Redis(2):内存模型
一、Redis内存统计 工欲善其事必先利其器,在说明Redis内存之前首先说明如何统计Redis使用内存的情况。 在客户端通过redis-cli连接服务器后(后面如无特殊说明,客户端一律使用redis-cli),通过info命令可以查看内存使用情…...
深入解析Diffusion和AsymmDiT:Mochi 1的高效AI视频生成之路
随着AI视频生成技术的迅猛发展,各种模型纷纷涌现,各自展现出独特的优势。近期,Genmo 推出了新一代视频生成模型——Mochi 1,以其非对称架构设计和高效生成流程在业界备受瞩目。作为开源模型,Mochi 1不仅在视觉生成质量…...
VMware capacity mismatch for disk错误解决办法:kb-vuln-1靶机
https://www.vulnhub.com/entry/kb-vuln-1,540/ 本机安装有: VMware Workstation 16 Pro 16.2.1 build-18811642VirtualBox 图形用户界面 版本 5.2.30 r130521 (Qt5.6.2) vm16.2支持wsl2,所以我得让vm16.2跑靶机,VirtualBox5.2可以导入靶机,但是无法开机(不支持wsl2),得升级 …...

Java Collection/Executor LinkedTransferQueue 总结
前言 相关系列 《Java & Collection & 目录》《Java & Executor & 目录》《Java & Collection/Executor & LinkedTransferQueue & 源码》《Java & Collection/Executor & LinkedTransferQueue & 总结》《Java & Collection/Execu…...

阿拉伯国家本地化测试的特点
针对阿拉伯国家的应用程序的本地化测试需要详细了解语言、文化背景、地区规范和技术细节,以符合阿拉伯语用户的期望。这些国家包括沙特阿拉伯、阿拉伯联合酋长国、科威特、卡塔尔、巴林和阿曼,具有独特的语言和文化因素,成功地本地化测试解决…...
申请前必知!关于「美国绿卡」的28个常见问题汇总!
01 美国绿卡的类别 美国绿卡分为多个类别,如亲属移民、职业移民、投资移民等。每个类别有不同的申请要求和优先级。选择最适合自己的类别,并深入了解相关法律和政策,是成功申请的第一步。 02 移民路径选择 根据个人情况(如职业…...

2024年十款超好用的图纸防泄密软件精选,十款优秀的图纸防泄密软件推荐
在当今竞争激烈的商业环境中,图纸作为企业的核心资产和智慧结晶,其安全性至关重要。一旦图纸泄露,可能会给企业带来巨大的经济损失和竞争劣势。因此,选择一款可靠的图纸防泄密软件成为了企业保护知识产权的关键。下面为大家推荐十…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...

高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
NPOI Excel用OLE对象的形式插入文件附件以及插入图片
static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...