按开发经验来说,本不该再犯这样的错误。幸好只过了3天,后悔还来得及。
我设想按照 prolog 的哲学,把世界理解为选择+操作。这个理解基于多方面的考虑:
1. 事实上,的确可以这样理解。比方用户
选择一段文字,右键列出可以处理该选择的
操作,复制,剪切等等,下一步用户便选择执行其中一项操作。
2. 操作的事务化。如果把操作理解为一个对象,操作有撤消方法,实现该方法可以轻松的实现命令链。
3. 操作的UI渲染。很容易对目前的操作渲染用户界面,如菜单项,工具栏项。
4. 权限控制。操作变成对象后,权限检查可以在操作中进行,结合第三项,可以广播到所有的UI元素,让它们变成灰色。
5. 自动获得异步能力。如从异步操作类派生的操作类,自动拥有异步操作的能力。
6. 插件化。可以以后补充插件,只要更换插件即有升级之功效。
根据以上原理,我制作了一个Selection / Action 框架。
这个框架按说并不复杂,封装之后得到了想要的效果,异步、UI渲染。
但实际开发和理论演绎是两回事。理论先进不等于开发就会跟着高效。如何协调二者的关系,需要有切实的洞察力。
prolog的义理毫无疑问是坚固牢靠的。但是VB8也好,c# 也好,都不是逻辑语言,不具备自动回溯的能力,需要一大堆的For Each,压栈归约来达到类似的效果。这并不是问题的最严重之处。
先从模块化来考虑如何达到同样的目的,有助于把问题澄清:
现在我们内心对目的已经很清楚,要达到12345项。
1. 选择后列出可能的操作,用户选择进行操作。我把操作放在选择类初始化代码里。这样固然达到了目的。但在接下来的开发中,由于有多少种选择几乎是固定的,完全可以通过申明全局变量来记录选择,之后检验操作(权限等等上下文环境)可否进行,渲染按组分好的UI控件,达到类似的功能。
2. 按vb的优势,把一个操作和多个控件关联,只要handles a.Click,b.Click… 就可以。使用操作类反而把问题复杂化。
3. 只要使用BackgroundWorker即可把现成的方法封装为异步的方法。
4. 命令链的实现。要用模块化实现命令链,难度较大。
模块化的局限显而易见。但在项目启动的时候,却必须用模块化的方式开发。
说在支离破碎的代码会严重影响开发进度。同一个变量在多个类传递,其心理成本、维护成本(例如要多传参数少传参数),都较同一文件大的多。
所以写 jsp 要比写 struts 快,主要一个原因就是一个表单的内容分散于各处,维护成本昂贵。
在项目收尾后,可以花一个下午,把所有的 sub 改成Action,自动获得上面所述的好处。