术语
应用定义与运行时
应用定义与运行时,指的是这样一条架构分界:一边是「应用是什么」——它的对象、字段、关系、权限、流程、动作和 API 的类型化、进版本库的声明;另一边是「谁在跑它」——一个在每次请求时读取这份声明、并由它推导出数据库、API、界面以及权限与审计执行的引擎;正是这条分界让定义可以带走、让引擎可以替换。
又称 定义与运行时分离声明与执行分离应用定义与应用运行时
在实践中
要看清这条线,最快的办法是看它不存在的时候会怎样。在一个「生成出来」的应用里,定义和运行时是同一个产物:生成器把一份说明变成控制器、表单和迁移脚本,从那一刻起,那份说明就成了历史文档。没有任何东西会再读它。改生成的代码,说明就错了;改说明,代码毫无反应。而在保留这条线的系统里,声明始终是活的源头——引擎在每次请求时都去查它,于是两者之间没有可以互相走散的缝隙,也没有一次需要有人记得去做的「重新生成」。
大家真正关心的后果是锁定,而它有常被混为一谈的两半。一个开放的定义格式,配上唯一一个能执行它的私有引擎,并不叫可移植——不管文件多好读:你可以把声明带到别处,那里没有任何东西跑得起来。一个开放的引擎,配上没有文档的内部格式,同样不叫可移植——你可以自己托管它,直到你想读懂它托管的到底是什么为止。可移植需要两半同时成立:一份不用运行就能读、能 diff 的定义,加上至少一个你自己能运维的运行时。
反对这条分界的最强论证值得原样摆出来:一个同时拥有两半的一体化系统,工程上可以做得更好。它可以让格式和引擎一起演进,做出那些必须同时改两边才能实现的能力,也避免了一个稳定声明格式所带来的兼容负担。这个论证对「单一产品、单一厂商」是成立的。它失效的时刻,是当有好几方开始依赖同一份声明——应用本身、调用它的 Agent、事后复盘的审计方,以及那些永远不会互相协调发版节奏的第三方工具。
实际的检验是两个问题,而且一下午就能答完。你能不能不运行就读完整个应用——打开一个文件,看清一个对象是什么、谁可以编辑它、哪一步需要审批?以及,另一个独立实现的运行时,能不能执行同样这批文件?第一个答「能」、第二个答「不能」是最常见的情况,值得诚实地承认,而不是算作通过。
这个术语用在哪里
真正用到这个术语的页面与文章。