Posted on 2008-12-31 22:08
mingj 閱讀(5350)
評論(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 應用開發框架的過程中一直堅持的,希望到時能展現給大家一個高效率而有符合編程哲學的好框架。