2010年4月11日星期日

从properties到dsl:知识描述的变迁

在一个系统之内,除了来来往往的数据之外,软件的架构本身,一般来说也可以区分出不变的和易变的部分。随着需求的日渐提升,对软件柔性化的要求越来越高。甲方不再满足于每次变更都要找乙方签订新合同,也不愿意回到自己养程序员的老路,于是,运行时变更成为了合情合理的需求。

想做变更,无非就是将易变项抽提出来给用户控制,把剩下的不变项保留在bin包里面,抽提出来的部分,纯文本的配置文件自然就成了最佳选择。当然,代码中需要做必要的变更,于是,程序也自然变成了两部分:负责管理功能模块/配置文件的框架,和执行具体业务的应用逻辑。整个程序的执行模式就变成了框架按照配置文件的描述,将应用逻辑组合成完整逻辑。最典型的就是诸如数据库配置或者功能模块是否启用。

很快的,这成为了新一代柔性应用程序的大趋势,但是用户对柔性的需求越来越高,配置文件需要描述的信息也越来越多,一开始,也许仅仅是简单表述一下在“状态A下执行模块甲”,渐渐的演进成“当角色1在状态A时,执行模块甲,乙,丙,否则,……”,简单的线性文件开始不够用,描述能力强大的xml成为了第一选择。

xml,xml,xml,从spring的applicationContext.xml到各mvc框架再到web容器的web.xml,处处都是xml的身影,更有诸如EOS普元之类试图包罗万象的框架,然而,随着越来越多的功能被挪进xml,xml也变的愈发臃肿,我们在xml中定义类,组装类,初始化类,给类增加横切点,控制类实例,等等,等等,xml渐渐成了第二编程语言。

然而,作为一个结构描述语言,xml从头到脚都没有期望成为一个编程语言的替代品,基于结构而非语义的meta约束,严格的层层嵌套格式。指望让xml成为拥有流程控制/局部变量的动态编程语言的替代品实在是强人所难。但是,xml纯文本的假象蒙蔽了很多人,无数人仍然乐而不疲的付出艰苦卓绝的努力,把xml几乎扩充成了一个完备图灵机,然后再配置上无数华丽的GUI,冠以“可视化编程”的美名,试图让用户在拖拖拽拽之间就能“设计程序”。

幸好,随着编译技术的突飞猛进,实现一门程序语言的成本越来越低,于是,我们有了DSL。

DSL,领域特定语言,不再是properties中的简单key-value对,也不是层层嵌套的xml,而是程序员喜闻乐见的,有变量有函数,有流程控制有循环,没准还有递归的编程语言,当然,不是C/CPP/Java/C#这种工业级语言,而更可能是诸如“设置流程=A”之类的专用语言,弱类型约束,函数作为first-class对象。它比xml强大,因为它的语法结构远比xml复杂,它拥有自描述能力,因为它的关键词完全可以面向具体业务量身定制。

多年以来,让软件能够模块化的组装,是无数程序员的梦想,从CORBA,到Dll,OCX,再到COM/DCOM,EJB,乃至最新的SOA,每个缩写都代表了软件模块化的一次努力。伴随着诸如Ruby,Govvry等动态语言崭露头角,DSL也成为了当红炸子鸡,用工业级语言编写模块,用动态语言或者DSL作为胶粘剂或者业务描述,是向这一终极目标迈出的一大步。

且慢,在欢呼之前,先让我们转头看一下身后,看一下老而弥坚的UNIX,我们就会惊讶的发现,如果你把每个UNIX程序当做一个模块,把Shell脚本作为胶粘剂,我们其实已经拥有了全部的关键元素,这就是UNIX的智慧,虽然现在已是2010年,我们仍然能从几十年前的UNIX中寻得灵感