Posted on 2008-12-31 22:08
mingj 阅读(5339)
评论(14) 编辑 收藏 所属分类:
framework 框架
play! framework 是一个面向小型网站开发的 rails-like 的 Java 框架,不仅在目录结构上,在系统 skeleton 生成上,也把 rails 学了个七七八八。最近和同事也在做一个 rails style 的 Java Web 应用开发框架,参考了 rails 的很多 feature,但更多的是按照自己的开发理念和哲学思想“拿来” rails 里面有借鉴意义的思想。面对号称 rails-like 的 play! framework,这几天身在海滩上,于是花了一些时间好好研究了 play! 的源代码一番。“看上去很美”,是读完代码后脑海中第一下涌现出来的想法,我承认我是OOafarian。
play! framework 5个“酷”的东西,看上去很美,但这些大都是建立在对 Java class 文件 hack 的基础上的。以 JPAModel 为例,任何它的子类 model 都是可以使用 rails style 的语法:User.findAll()。表面上看和 activerecord 的语法一样的,但实际上 play! 是通过在 JPAModel 里面定义这些静态方法,默认实现是抛出 RuntimeException,然后在 classloader 载入子类 class 文件的时候,通过增强每个 model class,使之具有这样类型安全的类方法。且不说这样实现是多么暴力和对开发人员不可理解,这与 rails 的实现是完全不一样的。ruby 因为是提供了 class 的继承体系,使得类方法也成为可以 override 的 class 类的实例方法,但是 Java 不提供 class 的继承和覆盖:这是 Java 的优势也是劣势。有人说这是语言的天性,但其实语言也是人们对世界进行抽象建模的一种折射,也反映的是人们的世界观和哲学思想。如果是我,如果依旧选择 Java 来做,我更倾向于保留 Java 的静态方法的优势和优雅,通过模式或者设计方法使之具有类似于动态语言的灵活性。这也是我和几位同事一致的看法。
那么,从一位受 OO 和 pattern 熏陶很深的 Java 程序员看来,看上去很美的 play! framework 华丽的袍子下有多少虱子呢?待我细细数来:
1. controller 里面充斥的 static void 方法,不 OO,不 testable,完全是过程化的代码。作者也是说了:
The Java code from the Controller class isn't really Object Oriented : it's mainly some procedural code.
当然,过程化还是面向对象,这个争论不是今天才有,不同的人在不同的上下文情景下都会选择最适合自己的开发方式。但是,作为受 OO 熏陶很深的我,这是不可接受的。
2. view 的 render 实现是继承自 RuntimeException。记得很早之前,还有人争论 Exception 作为程序出口和条件判断分支的使用,但自《Effective Java》一书以及其他编码风格介绍的书籍出来之后,这样的争论早已不知何处。Exception 和 Error 会有自己适合的场所,也有它们自己的正确含义,被滥用可不是它们的错。我想,即使是 JVM 被优化得性能完全不用考虑了,这样的处理思路也是不可以被团队成员理解、认同和接受的吧?
3. 暗地里修改代码,使用自己的classloader来大量增强或者修改class,甚至反编译 class。这样就导致很多增强的东西都是框架来强制性加入的,开发人员没有办法进行测试,也没有办法修改默认的实现。也许有人会觉得这样也挺好,觉得这样也够用,那也 OK。但是如果这些都建立在抛弃 Java 强大的静态类型安全,强大的 IDE 支持,强大的社区支持的基础之上,我是不能接受。
当然,play! framework 也是体现了一些很新颖的创新。比如使用 Http Server 来取代 J2EE Server,甚至是 Application Server。又比如通过动态编译代码来实现 hot swap。还比如使用 java.lang.instruments API 来定位 Exception 的位置。这些创新在一定程度上减轻了 Java web 应用开发过程中的“重”,给开发人员带来“轻”的感觉。但是,如果这些需要付出 Java 社区积累到几天的成果,完全重头再来,我想我会宁愿选择 ruby on rails。
当我们选择了 Java,我们看重的是强大的静态安全,看重的是强大的 IDE 支持和社区支持。虽然这些会给开发过程带来一定的“重”,但是米兰昆德拉说过,
可是,沉重便真的悲惨,而轻松便真的辉煌吗?
最沉重的负担压得我们崩塌了,沉没了,将我们钉在地上。可是在每一个时代的爱情诗篇里,女人总渴望压在男人的身躯之下。也许最沉重的负担同时也是一种生活最为充实的象征,负担越沉,我们的生活也就越贴近大地,越趋近真切和实在。
相反,完全没有负担,人变得比大气还轻,会高高地飞起,离别大地亦即离别真实的生活。他将变得似真非真,运动自由而毫无意义。
rails 之所以能轻,是因为它有 runit,有 rspec 来作为它的安全网,使之不会偏离方向。而 Java 也可以变得很轻,但这个轻却绝不是以抛弃 Java 的优势作为代价的。这也是我和几位同事在做 rails style 的 Java web 应用开发框架的过程中一直坚持的,希望到时能展现给大家一个高效率而有符合编程哲学的好框架。