理论起源与定位
(广义)可逆计算理论由国内架构师canonical于2007年提出,其思想源头并非传统软件工程,而是理论物理学。这一理论可以看作是继Feature Oriented Programming(FOP, 1997)和Delta Oriented Programming(DOP, 2010)之后,在软件产品线工程(Software Product Lines)领域的重大进展。
核心公式:软件构造的统一理论
该理论的核心思想可以通过一个简洁的公式来表达:
ini
App = Delta x-extends Generator<DSL>
即 Y = F(X) ⊕ Δ
这个公式具有强大的解释能力,为理解软件系统的构造和演化提供了新的视角。
对传统理论的继承与发展
1. 模型驱动架构(Model Driven Architecture)的演进
传统MDA采用App = Transformer(Model)
的模式,其中Transformer和Model都是预先定义的,这种刚性结构在长期演化中面临挑战。
可逆计算通过引入Δ差量机制,使模型转换过程具备了更好的灵活性,支持系统在生成过程中接受定制化修改,从而更适合实际项目的渐进式演化需求。 从理论脉络上看,可逆计算可以理解为将DOP(差量作为一等公民)与MDA(生成作为一等公民)这两种理念的深度整合:它既继承了MDA通过模型转换自动生成系统的主体能力,又通过DOP(Delta Oriented Programming)的差量思想为生成过程注入了应对变化和定制的灵活性。
2. 软件复用理念的深化
复用理念的发展脉络:
- 面向对象 :
A > B
(继承),能表达"派生类A比基类B多",但没有明确表达"多出来的部分是什么"。 - 组件化 :
A = B + C
(组合),将"多的部分"明确表达为可复用组件C。 - 可逆计算 :
B = A + (-C)
,不仅可以表达"多",还可以表达"减"
这一发展使得软件复用从"相同可复用"转向"相关即可复用 "。在实践中,这意味着不需要为了复用而拆解已有系统。例如,从系统X = A + B + C
到系统Y = A + B + D
,可以通过Y = X + Delta
来实现,其中Delta包含了(-C+D)
两个部分。
这种方法为软件产品线工程提供了新的实现路径:
ini
Effective System = Base ⊕ Δ_Industry ⊕ Δ_Region ⊕ Δ_Customer
基础产品可以独立演进,而定制需求被隔离在各自的Δ包中,从根本上解决了"核心产品与客户定制"的核心矛盾。
3. 领域特定语言的整合
从单一DSL向**DSL图册(Atlas)**的发展,使多个DSL能够有机协作。
横向DSL分解:特性向量空间
scss
App = G1(DSL1) ⊕ G2(DSL2) ⊕ Delta ~ [DSL1, DSL2, Delta]
通过多DSL组合+残差Δ,克服了单一DSL表达力有限的问题,形成了完整的描述能力。每个DSL专注于特定领域的表达,而Δ负责处理跨领域的协调和意外需求。
纵向DSL分解:多阶段软件生产线
ini
XMeta = Generator<XORM> ⊕ Δ_meta
XView = Generator<XMeta> ⊕ Δ_view
XPage = Generator<XView> ⊕ Δ_page
从ORM模型可以直接生成前端页面,但是划分为多个阶段,每个阶段可以补充额外的Delta信息。这种设计解决了传统MDA的两难困境:既不需要在模型中内置过多知识(避免模型过于复杂),又能通过Δ机制灵活应对意外需求(保持灵活性)。
4. 语言工作台(Language Workbench)的实用化
统一元模型(XDef):所有DSL都基于一个统一的元模型来定义,这使得可以快速开发新的DSL,并实现多个DSL的无缝嵌入和协同工作。
内置差量机制(x-extends):"变化"成为所有DSL都具备的一等公民和语言级特性,而非外部工具的附加能力。这意味着差量合并是语言内核的一部分,保证了语义的一致性。
多重表象支持:同一个DSL模型可以无损地在XML、JSON乃至Excel等多种形式之间转换。可视化设计器被看作是可视化表象,可以基于模型自动推导得到基本界面,然后通过Delta修正进行精细调整,实现"推导+修正"的工作模式。
5. 领域驱动设计的重新解读
DDD的传统理解是围绕"语义、约束、演化"三类不变性:
- 语义不变:通用语言在明确的限界上下文内构建模型
- 业务约束不变:以聚合作为一致性边界,集中维护业务规则
- 演化路径稳定:通过上下文映射、防腐层与领域事件进行跨边界协作
可逆计算将DDD重新解释为一个"空间-时间-语言-变化 "的思维框架,实现了从"先有对象,后有关系"到"先有空间,后有对象"的认知转变。
空间维度:限界上下文的作用是将作为背景存在的绝对空间划分为众多相对空间,空间的边界决定了内部的规律。防腐层是将多个子空间粘结为整体空间所需的坐标变换。
时间维度 :领域事件是状态空间的"差量(Δ)",遵循NewState = OldState ⊕ Event
的演化规律。一个实体(Entity)对应于一条具有内在活动性的时间线。CDC、EventSourcing等技术使得同时看见多条交叉的时间线成为可能。
语言维度:空间内部发生的事件使用领域语言描述,类似于物理现象使用坐标系统来描述,一个语言就是一个坐标系。传统的插件和扩展点机制可以看作是预先定义少量特制坐标,而完整的DSL则提供了覆盖整个语义空间的连续坐标系,使得变化可以在任意位置精确定位和施加。
变化维度:演化是坐标系的每一点上发生的变化,变化必然同时包含增与减,这对应于差量Δ中必须同时包含正元素和逆元素。
世界观的转变
在可逆计算的视角下,软件构造的思维模式发生了明显变化:
传统世界观:粒子视角 (Particle View)
- 基本单元:世界是由离散的、有边界的"对象"、"组件"、"模块"构成的软件基本"粒子"
- 构造方式 :通过侵入式组装,将这些"粒子"通过调用、继承、组合等方式硬性地连接在一起
- 关注焦点:单个对象的内部状态和行为,思考的是"这个对象是什么?它能做什么?"
新世界观:波动视角 (Wave View)
- 基本单元 :世界是由作为背景的**连续模式(即坐标系/场)和作用于其上的扰动(即差量/Δ)**共同构成的
- 构造方式 :通过非侵入式叠加,不同的"波"(差量包Delta)在同一个"场"(基础结构X)中相互干涉、叠加
- 关注焦点 :作为背景的坐标系如何演化 ,以及变化(Δ)自身如何组合、传递和相互作用,思考的是"在哪个坐标系下,发生了什么变化?"
可逆计算的广泛体现:从理论到实践
可逆计算的核心范式 结果 = Generator ⊕ Δ 已在众多基于差量概念的创新实践中得到成功体现。
-
Docker :
FinalImage = DockerBuild<Dockerfile> overlay-fs BaseImage
,其中联合文件系统(overlay-fs)正是差量合并操作⊕的具体实现, DockerBuild工具可以看作是基于领域特定语言DockerFile的生成器。 -
Kustomize:
最终配置 = 基础配置 ⊕ 环境差量
,通过非侵入式的补丁(Patch)来管理不同环境的应用变体。 -
前端虚拟DOM:
ΔDOM = render(NewState) - render(OldState)
, 前端React框架及其虚拟DOM(VDOM)差分算法,精确定义了状态更新的差量化过程。
这些来自不同领域的技术创新,尽管其具体实现和目标各异,但其内在的"差量优先"逻辑与可逆计算的理论内核高度一致。这表明,可逆计算并非一个孤立的设想,而是对一系列先进工程实践背后共性的、更深层次规律的提炼与总结。
理论意义与影响
可逆计算的视角将我们从"存在"的本体论,引向了"生成"的演化论。我们对软件的理解,从静态的、孤立的"实体",转向了动态的、关联的"过程"。这一理论不仅提供了具体的技术解决方案,更重要的是提供了一种理解软件构造和演化的全新思维框架,为应对日益复杂的软件系统提供了理论基础和实践路径。
参考文档
- 可逆计算:下一代软件构造理论
- DDD本质论之理论篇
- DDD本质论之实践篇
- 对DDD本质论一文的解读
- 广义可逆计算: 一个软件构造范式的正名与阐释
- 从可逆计算看Delta Oriented Programming
- Nop如何克服DSL只能应用于特定领域的限制?
基于可逆计算理论设计的低代码平台NopPlatform已开源:
- gitee: gitee.com/canonical-e...
- github: github.com/entropy-clo...
- gitcode:gitcode.com/canonical-e...
- 开发示例:gitee.com/canonical-e...
- 可逆计算原理和Nop平台介绍及答疑:www.bilibili.com/video/BV14u...
- 官网国际站: nop-platform.github.io/
- 网友Crazydan Studio建立的Nop开发实践分享网站: nop.crazydan.io/