模拟语法结构 :: 梦想风暴
来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=115466 存档链接: https://web.archive.org/web/20040915200646id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=115466
梦想风暴 一个小程序员的信口开河 <<<平凡也伟大 | 主页 | 先作用户,后作程序员>>> 模拟语法结构 2004-03-08 项目组的一个兄弟提出一个令我目瞪口呆的想法,模拟语法结构。 实际做法很简单,下面以Java语言讲解一番。 学过编程语言的都知道,语句是程序设计中的一个基本单位,大语句由小语句组成。 我们定义语句如下: public interface Statement { public void execute(Context context) throws Exception; } 其中context是用来存放执行语句所需的相关信息的一个接口。 一旦看到了语句的出现,我们很自然就会联想到顺序语句、选择语句和循环语句等等,这几种语句也是语句,看起来这是废话,实际上我指的是LSP(Liskov替换原则)。所以,我们让这几种语句也成为语句,下面给出一种可能的顺序语句实现: public final class Sequence implements Statement { private Statement[] statements; public Sequence(final Statement[] statements) { this.statements = statements; } public void setStatements(final Statement[] statements) { this.statements = statements; } public void execute(Context context) throws Exception { for (int i = 0; i < this.statements.length; i++) { this.statements[i].execute(context); } } } 结构很简单,顺序语句由一堆“语句”组成,execute就是顺序调用就OK了。 我们可以用同样的方法实现选择语句、循环语句。 到这里,我们可能还无法看出这种结构的优点:语言已经提供了很好的结构,为什么要模拟? 这么做最吸引我的地方就在于它的可配置性。 IoC,Robert Martin叫它DIP,对了,Martin Flower给它改了个名叫Dependency Injection,最近比较火爆,《程序员》2004年第三期上有一篇gigix翻译Martin Flower的那篇《Inversion of Control Containers and the Dependency Injection pattern》比较详细的讨论了它。 稍微对它熟悉一点的话,我们不难看出,上面Sequence的实现用到了setter和constructor,它们分别代表了IoC的type 2和type 3,通过这种方式,我们就可以很轻松的配置自己的应用了。 我知道这么说,还会让人有一头雾水的感觉。 我们应用的新版本是在SpringFramework的基础上构建起来的,SpringFramework就是一个很好的IoC容器。它让我们可以通过配置文件来构建整个应用。 假设BasicProcessor1和BasicProcessor2是两个实现了Statement接口的类。使用SpringFramework,我们可以这样构建自己的应用。 其中,processor1和processor2可以分别看作BasicProcessor1和BasicProcessor2的instance。flow是Sequence的一个instance。 当系统生成时,SpringFramework会自动调用setStatements将processor1和processor2作为一个数组设置到flow中去。这样就省去了我们手工配置系统的繁琐工作。 说起来很神奇,其实这是利用了JavaBean的一些特性。 回到我们前面的讨论上。 当这种配置方法和模拟语法结构相结合,威力就显现出来了。 我们完全可以在不改动系统源代码的情况下,修改系统生成的配置文件,从而达到改变流程的目的。 如果有了新的需求,我们可以单独开发一个Statement,然后再把它配置到系统中,而原有的代码无需任何改动。 多么美妙的一种想法啊! 放任我们的思绪继续前行! 真正控制我们应用结构的是我们的配置文件。在SpringFramework中,在一个应用中可以有多个配置文件,我们可以把组件定义放在一起,而把流程控制的部分放在一起。于是,我们只要修改流程控制的部分就可以达到对整个系统的重新设定。 前面已经说过,模拟语法结构无非是顺序语句、选择语句、循环语句等等,从本质上说,它就是一门语言,而我们的流程配置文件就是这种语言的源代码,唯一的缺陷就是相对烦琐一些。 如果我们再向前迈一步,把模拟的语法结构变成真正的语法结构,那它就会成为一门真正的语言。编译器的工作就是将一种语言转化为另一种语言,而我们流程配置文件本身就是模拟语法结构的源文件。我们完全可以开发一个小型的编译器,将这种语言编译生成我们流程控制文件。 达到这一步的话,以后的应用开发就成了用这种小语言来编写控制流程,只有真正的新东西才需要我们编写Java代码,这将极大的降低我们开发的工作量。 或许这会引起某些人的不屑,前面说过模拟语法结构是为了不编译代码,如果开发自己的编译器编译和用Javac编译有什么不同? 复杂程度。 二者所在的层次不同,我们用自己的语言控制的流程,而不是细节。 如果把我们的语言比作高级语言的话,那么直接用Java编写的代码无异于现在的汇编,想必大家对二者的开发速度都有自己的比较吧! 模拟语法结构,这种做法本身上没有什么技术难度,难的在于把它提炼出来,惯性思维常常会局限我们的思路。 或许不经意间,又一个好想法浮现于脑海之中。 不要犹豫,赶快操起键盘实现它! dreamhead 发表于 2004-03-08 22:18 引用Trackback(0) | 编辑 Comments 实在是一个好想法,但你的表达更好,佩服佩服!! 梦想风暴回复jxb8901说: 多谢你的鼓励,欢迎多多关注梦想风暴。Blogbus恢复正常,梦想风暴也将恢复正常。 (2004-03-26 14:49) jxb8901 ( ) 发表于 2004-03-26 10:11 路过,你的文章真好。 我觉得IBM的WorkFlow(工作流)也许是基于这样的思想实现的。WF中的流程节点(Activity)也许就是你文中的组件定义,而节点间的控制流也许就是流程控制部分,这样WF实现了任意调整流程顺序的功能,也许就是上文思想的一个真实再现。这么一分析,更清晰了,WF的BuildTime简直就是一个IDE开发工具,而生成的.cfg文件就是我们的程序,Fmcibie.EXE就是编译器。 Swing ( ) 发表于 2004-08-26 19:19 发表评论 最近更新 自其不变而观之 初窥进程 叫我如何“面向接口” 自掘坟墓 复杂系统的5个属性 平民神话 我的J2EE误区 项目坚壳 重载游戏 惊天逆转