解决侵入的根本方法讨论 博客分类: 思想 框架编程Spring应用服务器Bean
最近又看到一些关于框架侵入性的讨论, 有些想法, 谨此抛砖引玉.
我觉得软件开发框架之所以跟侵入性纠缠不清, 根本的原因还是框架要支持应用的某种/某些逻辑和功能, 可以说是部分的去实现应用的目标. 但是这些功能如果不能让应用去定制, 其现实应用代价就又很微渺了. 所以框架是需要和应用交流的, 而交流的主要目的是为了定制.
想到这个地方, 我的反应是声明式编程, 让应用通过某种方式表达出自己的定制需求, 这个表达的方式就可以是多种多样的了: 通过遵循约定, 继承特定框架基类, 实现特定框架接口, 标注Annotation, 编写配置文件, 调用框架API, 等等.
而像Java这样的静态语言所能支持的表达方式, 无论怎么看都可以挂上 "侵入性" 的标签, 因为如果框架一旦定了它要求应用采纳的方式, 应用就得跟着它走. 在应用需求表达方式问题上, 框架之间的相容性既没有理论研究, 更没有实践习惯.
这里提到 "框架的侵入性" 好像用的是它最宽泛的涵义, 就是对应用编程行为的影响. 要是这么说任何框架都不可能没有侵入性了, 只是有些让应用开发人员的日子很难过, 有些则好一点. 不过以目前的软件体系局势来看, 绝对的 "侵入性" 问题还没有办法解决, 更现实一点, 似乎只有它对单元化开发和测试的影响比较有可能解决, 眼下讨论才比较有现实意义.
不过对下一代软件框架体系, 我倒是感到有些期望, 随着Annotation的成熟和普及, 对于基于Java的开发来说, 我觉得这个趋势已经临近了. 我的想法是可以运用一下逆向思维, 既然应用与框架的交互无可避免, 那么与其被动的接受框架的 "侵入" 不如由应用自身采取主动行为, 进行 "引入".
应用的主动引入可以从已有的 声明式编程 出发, 对于比较大的综合应用方向, 比如 Web应用, 以制定通用的应用需求表达规范为手段, 通过公开的规范, 协调应用程序和系统框架之间的交流. 这听起来就是JCP要为JavaEE做的事情, 是的, 以截至到目前的软件体系局势, 这个事情还不得不由人力, 物力, 财力丰厚的商业实体去完成, 它们也必须在这个领域有足够的商业利益吸引也才有动力去做.
但是同样是JCP出来的J2EE规范, Servlet很成功, 而EJB却不是. 并且Servlet很好的解决了它那个年代的Web开发问题, 而软硬件的发展所推动出来的新需求, 新问题又飞快增长, 对新规范的需求不仅是本身增长很快, 它的增长速度也会随着时间增长. JCP已经开始显得笨拙且乏力了.
一个本质性的问题是: 目前的规范是基于少量编程语言API的大部分的自然语言描述. 基于这样的模式, 成本太高, 就算是目前的大型开源社区要开发自己的体系规范也会是难上加难.
在这个方向上, DSL(Domain Specific Language)是个很好的创意, 可以有针对性的简化专门领域的规约方式. 不过, 我觉得还有DSL没有特别关注的一点, 就是同一种语言中声明与实现语法的分离与融汇:
DSL倾向于作为一种声明式的语言, 被设计为独立使用, 它很可能由另一种通用语言进行解释而实现. 它的语法很可能可以直接调用实现语言, 但很难变成编写应用所用语言的一部分. (我很期望它变成应用代码的声明部分)
回到解决侵入性的问题上来, 我设想的方式是目前还没有的, 至少还没有系统化. 那就是可以用一种语法给应用编程语言增加用于声明的语法, 同时这种语法也照顾到给应用声明的需求提供实现的系统编程语言语法, 从而这样的语法可以同时 表达/约束/支持 应用声明和系统实现.
看上去动态语言在这个方向上有最深厚的长远潜力, 不过用于有分析需求的通用工业开发领域, 动态语言要走的路还有点长.
目前基于Java的开发, 利用起Annotation机制会在这个方向上有长足进展, 应用通过引用标注来声明需求, 系统在编译时通过Annotation Processor以及Language Model, 在运行时通过反射, 两者结合起来去理解和实现应用的需求. 而定义和引用Annotation都受到新增的Java语法约束.
不过基于Annotation机制的 应用/系统 交流有时候还是需要一些自然语言描述的规范, 好在这个已经比纯粹描述/理解大篇的约定和接口调用逻辑顺序简易多了. 同时Annotation引用只能放在modifier的位置还是一个过大的约束, 这个还需要Java语言进一步的演进去解决.
总结下来, 系统框架通过 "侵入" 要达到的 应用定制 目的是不可避免的, 而要解决被动的受到 "侵入" 的局面, 我所能想到的最好方法就是去主动 "引入". 而 "引入" 所能达到的 "主动" 程度取决于其方式方法的灵活程度和负面影响大小. 当应用的特定需求可以通过统一的(声明)方式利用大多不同系统(包括测试时的Mock系统)而实现时, 应用的 "引入" 行为也就达到了一个比较理想的主动程度, 从而可以视为没有被特定系统 "侵入" 了.