模型驱动的数学原理

    一种技术思想如果确实能够简化编程,有效降低系统构造的复杂性,那么它必然具有某种内在的数学解释。反之,无论一种技术机制显得如何华丽高深,如果它没有清晰的数学图象,那么就很难证明自身存在的价值。对于模型驱动架构(MDA),我长期以来一直都持有一种批判态度。(Physical Model Driven http://canonical.iteye.com/blog/29412 )。原因就在于“由工具自动实现从平台无关模型(PIM)向平台相关模型(PSM)的转换”这一图景似乎只是想把系统从实现的泥沼中拯救出来,遮蔽特定语言,特定平台中的偶然的限制条件,并没有触及到系统复杂性这一核心问题。而所谓的可视化建模充其量不过是说明人类超强的视觉模式识别能力使得我们可以迅速识别系统全景图中隐含的整体结构,更快的实现对系统结构的理解,并没有证明系统复杂性有任何本质性的降低。不过如果我们换一个视角, 不把模型局限为某种可视化的结构图,而将它定义为某种高度浓缩的领域描述, 则模型驱动基本上等价于根据领域描述自动推导得到最终的应用程序。沿着这一思路,Witrix平台中的很多设计实际上可以被解释为模型定义,模型推导以及模型嵌入等方面的探索。这些具体技术的背后需要的是比一般MDA思想更加精致的设计原理作为支撑。我们可以进行如下抽象分析。(Witrix架构分析 http://canonical.iteye.com/blog/126467

1. 问题复杂?线性切分是削减问题规模(从而降低问题复杂性)的通用手段,例如模块(Module)。(软件中的分析学 http://canonical.iteye.com/blog/33885

App = M1 + M2 + M3 + ...
 

    
2. 分块过多?同态映射是系统约化的一般化策略,例如多态(polymorphism)。(同构与同态:认识同一性 http://canonical.iteye.com/admin/blogs/340704

    (abc,abb,ade,...) -> [a],   (bbb, bcd,bab,...) -> [b]

 

3. 递归使用以上两种方法,将分分合合的游戏进行到底,推向极致。

4. 以少控多的终极形态?如果存在,则构成输入与输出之间的非线性变换(输入中局部微小变化将导致输出中大范围明显的变化)。

App = F(M)

 

5. 变换函数F可以被诠释为解释器(Interpreter)或者翻译机,例如工作流引擎将工作流描述信息翻译为一步步的具体操作,工作流描述可以看作是由底层引擎支撑的,在更高的抽象层面上运行的领域模型。但是在这种观点下,变换函数F似乎是针对某种特定模型构造的,引擎内部信息传导的途径是确定的,关注的重点始终在模型上,那么解释器自身应该如何被构造出来呢?

App ~ M

 

6. 另外一种更加开放的观点是将变换函数F看作是生成器(Generator)或者推理机。F将根据输入的信息,结合其他知识,推理生成一系列新的命题和断言。模型的力量源于推导。变换函数F本身在系统构造过程中处于核心地位,M仅仅是触发其推理过程的信息源而已。F将榨干M的最后一点剩余价值,所有根据M能够确定的事实将被自动实现,而大量单靠M自身的信息无法判定的命题也可以结合F内在的知识作出判断。生成器自身的构造过程非常简单--只要不断向推理系统中增加新的推理规则即可。语言内置的模板机制(template)及元编程技术(meta programming),或者跨越语言边界的代码生成工具都可以看作是生成器的具体实例。(关于代码生成和DSL http://canonical.iteye.com/blog/275015 )

App = G<M>
 

7. 生成器G之所以可以被独立实现,是因为我们可以实现相对知识与绝对知识的分离, 这也正是面向对象技术的本质所在。(面向对象之形式系统 http://canonical.iteye.com/blog/37064

G<M> ==> G = {m => m.x(a,b,c);m.y(); ... }
 

8. 现实世界的不完美,就在于现实决不按照我们为其指定的理想路线前进。具体场景中总是存在着大量我们无法预知的“噪声”,它们使得任何在“过去”确立的方程都无法在“未来”保持持久的平衡。传统模型驱动架构的困境就在于此。我们可以选择将模型M和生成器G不断复杂化,容纳越来越多的偶然性,直至失去对模型整体结构的控制力。另外一种选择是模型在不断膨胀,不断提高覆盖能力的过程中,不断的空洞化,产生大量可插入(plugin)的接入点,最终丧失模型的推理能力,退化成为一种编码规范。Witrix平台中采用的是第三种选择:模型嵌入--模型中的多余信息被不断清洗掉,模型通过精炼化来突出自身存在的合理性,成为更广泛的运行环境中的支撑骨架。(结构的自足性 http://canonical.iteye.com/blog/482620

App != G0<M0>  , App != G0<M1>, App = G1<M1> 
 

9. 现在的问题是:如何基于一个已经被完美解决的重大问题,来更有效率的搞定不断出现但又不是重复出现的小问题。现在我们所需要的不是沿着某个维度进行均匀的切分,而必须是某种有效的降维手段。如果我们可以定义一种投影算子P, 将待解决的问题投射到已经被解决的问题域中,则剩下的补集往往可以被简化。(主从分解而不是正交分解 http://canonical.iteye.com/blog/196826

dA = App - P[App]  = App - G0<M0>
 

10. 要实现以上微扰分析策略,前提条件是可以定义逆元,并且需要定义一种精细的粘结操作,可以将分散的扰动量极为精确的应用到基础系统的各处。Witrix平台的具体实现类似于某种AOP(面向切面编程)技术。(逆元:不存在的真实存在 http://canonical.iteye.com/blog/325051

App = A + D + B = (A + B + C) - C + D = App0 + (-C + D) = G0<M0> + dA
 

11. 模型驱动并不意味着一个应用只能由唯一的一个模型来驱动,但是如果引入多个不同形式的模型,则必须为如下推理提供具体的技术路径:
  A. 将多个模型变换到共同的描述域
  B. 实现多个模型的加和
  C. 处理模型之间的冲突并填补模型之间的空白

在Witrix平台中模型嵌入/组合主要依赖于文本化及编译期运行等机制。(文本化 http://canonical.iteye.com/blog/309395

App = Ga<Ma> + Gb<Mb> + dA
 

12. 系统的开发时刻t0和实施时刻t1一般是明确分离的,因此如果我们要建立一个包含开发与实施时刻信息的模型,则这一模型必须是含时的,多阶段的。关于时间,我们所知道的最重要的事实之一是“未来是不可预知的”。在t0时刻建立的模型如果要涵盖t1时刻的所有变化,则必须做出大量猜测,而且t1时刻距离t0时刻越远,猜测的量越大,“猜测有效”这一集合的测度越小,直至为0。延迟选择是实现含时系统控制的不二法门。
   在Witrix平台中,所有功能特性的实现都包含某种元数据描述或者定制模板,因此结合配置机制以及动态编译技术既可实现多阶段模型。例如对于一个在未来才能确定的常量数组,我们可以定义一个Excel文件来允许实施人员录入具体的值,然后通过动态编译技术在编译期解析Excel文件,并完成一系列数值映射运算,最终将其转化为编译期存在的一个常量。这一过程不会引入任何额外的运行成本,也不要求任何特定的缓存机制,最终的运行结构与在未来当所有信息都在位之后再手写代码没有任何区别。(D语言与tpl之编译期动作 http://canonical.iteye.com/blog/57244

App(t1) = G(t0,t1)<M(t0,t1)> + dA(t0,t1)
 

13. 级列理论提供了一个演化框架,它指出孤立的模型必须被放在模型级列中被定义,被解释。(关于级列设计理论 http://canonical.iteye.com/blog/33824

M[n] = G<M[n-1]> + dM[n]   
 

14. 推理的链条会因为任何局部反例的出现而中断。在任意时空点上,我们能够断言的事实有哪些?信息越少,我们能够确定的事实越少,能够做出的推论也就越少。现在流行的很多设计实质上是在破坏系统的对称性,破坏系统大范围的结构。比如明明ORM容器已经实现所有数据对象的统一管理,非要将其拆分为每个业务表一个的DAO接口。很多对灵活性的追求完全没有搞清楚信息是对不确定性的消除,而不确定性的减少意味着限制的增加,约束的增加。(From Local To Global http://canonical.iteye.com/blog/42874

   组件/构件技术的宣言是生产即组装,但是组装有成本,有后遗症(例如需要额外的胶水或者螺钉)。软件的本质并不是物质,而是信息,而信息的本质是抽象的规律。在抽象世界中最有效的生产方式是抽象的运算,运算即生产。组件式开发意味着服从现有规律,熟练应用,而原理性生产则意味着不断创造新的规律。功能模块越多,维护的成本越高,是负担,而推理机制越多,生产的成本越低,是财富。只有恢复软件的抽象性,明确把握软件构造过程内在的数学原理,才能真正释放软件研发的生产力。(从编写代码到制造代码 http://canonical.iteye.com/blog/333167

 

 

注解1:很多设计原则其实是在强调软件由人构造由人理解,软件开发本质上是人类工程学,需要关注人类的理解力与协作能力。例如共同的建模语言减少交互成本,基于模型减少设计与实现的分离,易读的代码比高性能的代码更重要,做一件事只有唯一的一种方式等。

注解2:生成系统的演绎远比我们想象的要深刻与复杂得多。例如生命的成长可以被看作是在外界反馈下不断调整的生成过程。

注解3:领域描述是更紧致但却未必是更本质的表达。人类的DNA如果表达为ATGC序列完全可以拷贝到U盘中带走,只要对DNA做少量增删,就可以实现老鼠到人类的变换(人类和老鼠都有大约30000条基因,其中约有80%的基因是“完全一样的”,大约共享有99%的类似基因),但是很难认为人类所有智慧的本质都体现在DNA中,DNA看起来更像是某种序列化保存形式而已。

注解4:模型转换这一提法似乎是在强调模型之间的同构对应,转换似乎总是可以双向进行的,仅仅是实现难度限制了反向转换而已。但是大量有用的模型变换却是单向的,变换过程要求不断补充新的信息。

注解5:模型驱动在很多人看来就是数据库模型或者对象模型驱动系统界面运行,但实际上模型可以意指任意抽象知识。虽然在目前业内广泛流行的对象范式下,所有知识都可以表达为对象之间的关联,但是对象关系(名词之间的关联关系)对运算结构的揭示是远远不够充分的。很多时候所谓的领域模型仅仅是表明概念之间具有相关性,但是如果不补充一大段文字说明,我们对于系统如何运作仍然一知半解。数学分析其实是将领域内在的意义抽空,仅余下通用的形式化符号。

 

注解6:模型本身如果体现的是抽象的规律,则我们有可能只需要在少量简化的场景下验证模型,然后即可将其推广应用到更加复杂的场景中,这样会本质上降低测试的难度。

你可能感兴趣的:(数据结构,编程,Excel,Blog,领域模型)