OOPAA

          Focusing on OO, Patterns, Architecture, and Agile
          posts - 29, comments - 75, trackbacks - 0, articles - 0
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理


           play! framework 是一個面向小型網(wǎng)站開發(fā)的 rails-like 的 Java 框架,不僅在目錄結(jié)構(gòu)上,在系統(tǒng) skeleton 生成上,也把 rails 學(xué)了個七七八八。最近和同事也在做一個 rails style 的 Java Web 應(yīng)用開發(fā)框架,參考了 rails 的很多 feature,但更多的是按照自己的開發(fā)理念和哲學(xué)思想“拿來” rails 里面有借鑒意義的思想。面對號稱 rails-like 的 play! framework,這幾天身在海灘上,于是花了一些時間好好研究了 play! 的源代碼一番。“看上去很美”,是讀完代碼后腦海中第一下涌現(xiàn)出來的想法,我承認我是OOafarian。
           
           play! framework 5個“酷”的東西,看上去很美,但這些大都是建立在對 Java class 文件 hack 的基礎(chǔ)上的。以 JPAModel 為例,任何它的子類 model 都是可以使用 rails style 的語法:User.findAll()。表面上看和 activerecord 的語法一樣的,但實際上 play! 是通過在 JPAModel 里面定義這些靜態(tài)方法,默認實現(xiàn)是拋出 RuntimeException,然后在 classloader 載入子類 class 文件的時候,通過增強每個 model class,使之具有這樣類型安全的類方法。且不說這樣實現(xiàn)是多么暴力和對開發(fā)人員不可理解,這與 rails 的實現(xiàn)是完全不一樣的。ruby 因為是提供了 class 的繼承體系,使得類方法也成為可以 override 的 class 類的實例方法,但是 Java 不提供 class 的繼承和覆蓋:這是 Java 的優(yōu)勢也是劣勢。有人說這是語言的天性,但其實語言也是人們對世界進行抽象建模的一種折射,也反映的是人們的世界觀和哲學(xué)思想。如果是我,如果依舊選擇 Java 來做,我更傾向于保留 Java 的靜態(tài)方法的優(yōu)勢和優(yōu)雅,通過模式或者設(shè)計方法使之具有類似于動態(tài)語言的靈活性。這也是我和幾位同事一致的看法。
           
           那么,從一位受 OO 和 pattern 熏陶很深的 Java 程序員看來,看上去很美的 play! framework 華麗的袍子下有多少虱子呢?待我細細數(shù)來:
           1. controller 里面充斥的 static void 方法,不 OO,不 testable,完全是過程化的代碼。作者也是說了:
           
           The Java code from the Controller class isn't really Object Oriented : it's mainly some procedural code.
           
           當(dāng)然,過程化還是面向?qū)ο螅@個爭論不是今天才有,不同的人在不同的上下文情景下都會選擇最適合自己的開發(fā)方式。但是,作為受 OO 熏陶很深的我,這是不可接受的。
           
           2. view 的 render 實現(xiàn)是繼承自 RuntimeException。記得很早之前,還有人爭論 Exception 作為程序出口和條件判斷分支的使用,但自《Effective Java》一書以及其他編碼風(fēng)格介紹的書籍出來之后,這樣的爭論早已不知何處。Exception 和 Error 會有自己適合的場所,也有它們自己的正確含義,被濫用可不是它們的錯。我想,即使是 JVM 被優(yōu)化得性能完全不用考慮了,這樣的處理思路也是不可以被團隊成員理解、認同和接受的吧?
           
           3. 暗地里修改代碼,使用自己的classloader來大量增強或者修改class,甚至反編譯 class。這樣就導(dǎo)致很多增強的東西都是框架來強制性加入的,開發(fā)人員沒有辦法進行測試,也沒有辦法修改默認的實現(xiàn)。也許有人會覺得這樣也挺好,覺得這樣也夠用,那也 OK。但是如果這些都建立在拋棄 Java 強大的靜態(tài)類型安全,強大的 IDE 支持,強大的社區(qū)支持的基礎(chǔ)之上,我是不能接受。
           
           當(dāng)然,play! framework 也是體現(xiàn)了一些很新穎的創(chuàng)新。比如使用 Http Server 來取代 J2EE Server,甚至是 Application Server。又比如通過動態(tài)編譯代碼來實現(xiàn) hot swap。還比如使用 java.lang.instruments API 來定位 Exception 的位置。這些創(chuàng)新在一定程度上減輕了 Java web 應(yīng)用開發(fā)過程中的“重”,給開發(fā)人員帶來“輕”的感覺。但是,如果這些需要付出 Java 社區(qū)積累到幾天的成果,完全重頭再來,我想我會寧愿選擇 ruby on rails。
           
           當(dāng)我們選擇了 Java,我們看重的是強大的靜態(tài)安全,看重的是強大的 IDE 支持和社區(qū)支持。雖然這些會給開發(fā)過程帶來一定的“重”,但是米蘭昆德拉說過,
           
              可是,沉重便真的悲慘,而輕松便真的輝煌嗎?
              最沉重的負擔(dān)壓得我們崩塌了,沉沒了,將我們釘在地上。可是在每一個時代的愛情詩篇里,女人總渴望壓在男人的身軀之下。也許最沉重的負擔(dān)同時也是一種生活最為充實的象征,負擔(dān)越沉,我們的生活也就越貼近大地,越趨近真切和實在。
              相反,完全沒有負擔(dān),人變得比大氣還輕,會高高地飛起,離別大地亦即離別真實的生活。他將變得似真非真,運動自由而毫無意義。

           rails 之所以能輕,是因為它有 runit,有 rspec 來作為它的安全網(wǎng),使之不會偏離方向。而 Java 也可以變得很輕,但這個輕卻絕不是以拋棄 Java 的優(yōu)勢作為代價的。這也是我和幾位同事在做 rails style 的 Java web 應(yīng)用開發(fā)框架的過程中一直堅持的,希望到時能展現(xiàn)給大家一個高效率而有符合編程哲學(xué)的好框架。


          評論

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-01 21:14 by 7047
          Play! 應(yīng)該是借鑒django吧

          # re: 看上去很美 --OOafarian對play!框架的幾點看法[未登錄]  回復(fù)  更多評論   

          2009-01-01 21:17 by woods
          web 開發(fā)總是以rails 是一件很恐怖的事情

          就像當(dāng)年ejb一樣

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-02 19:09 by mingj
          @7047
          django我倒是不熟,只是 play!宣稱rails-like,所以也是這樣理解的

          能詳細比較一下django和play么?

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-02 23:10 by hcom
          我認同Play作者的做法,在Controller 中寫大量的static方法沒什么不好的。

          一個很新穎的框架。

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-02 23:13 by hcom
          請問博主,關(guān)于play的效率,有沒有研究過?不知道play效率如何?

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-03 10:59 by mingj
          @hcom
          這個就是見仁見智了,也沒有唯一答案
          作為堅持OO 和 Testable的“狂熱分子”:)
          我是不能接受的

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-03 11:01 by mingj
          @hcom
          這個倒沒有研究
          因為我只是想研究里面一些比較新穎的東西和想法

          如果你能花些時間做這方面測試
          那對于我們就再好不過了:)

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-03 16:57 by hcom
          博主:
          “但是如果這些都建立在拋棄 Java 強大的靜態(tài)類型安全,強大的 IDE 支持,強大的社區(qū)支持的基礎(chǔ)之上,我是不能接受” 這句話我不認同。

          我大體看了一下play!的文檔,拿他的例子試驗了一下,(但可能沒有像你這樣深入的了解),發(fā)現(xiàn)play并沒有拋棄Java 強大的靜態(tài)類型安全,也可以很方便的使用Eclipse啊?比如他有一個命令:eclipsify,可以很方便的生成Eclipse工程,導(dǎo)入Eclipse后跟普通的Eclipse工程沒啥區(qū)別......導(dǎo)入的Play app的代碼,就是普通的java代碼,Eclipse照樣會進行檢查的。與使用Tomcat不同的是,Debug的時候需要使用Eclipse的遠程調(diào)試功能,也是可以很方便的進行debug調(diào)試。

          關(guān)于Testable,我沒有細看,我看他有一個test的命令,另外文檔中也專門有關(guān)于Test的說明。Play是推崇領(lǐng)域模型的,對領(lǐng)域模型可以很方便的測試的..

          另外強大的社區(qū)支持是指的什么?是優(yōu)秀的第三方開源產(chǎn)品嗎?貌似Play并不排斥這些東西.

          我是剛剛接觸play,希望共同探討。



          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-03 17:04 by hcom
          我看過一點Grails,:)總是不能深入,感覺Grails才是拋棄了“Java 強大的靜態(tài)類型安全,強大的 IDE 支持”..而Play并沒有...

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-04 18:09 by ajf
          play play俺整地java快速平臺ajf
          http://www.aygfsteel.com/ajf/archive/2009/01/03/249618.html

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-05 13:51 by pythonfly
          但實際上 play! 是通過在 JPAModel 里面定義這些靜態(tài)方法,默認實現(xiàn)是拋出 RuntimeException
          JPAModel是實現(xiàn)了值和操作合二為一的富對象。至于里面的靜態(tài)方法這也是符合OO標準的吧。難道rails的不是靜態(tài)方法嗎?User.save()這樣的用法不是靜態(tài)方法?User是一個實例而非class?
          JPAModel里面有異常,那是防止你在調(diào)用沒有的方法的時候而拋出的異常,這樣使用異常沒有什么不妥當(dāng)。
          JPAModel沒有使用修改字節(jié)碼增強,沒有任何增強的地方。只是單純的對JPA的一種封裝而已。

          java是沒有可以動態(tài)給一個對象增加一個方法的功能,而且無論如何也沒有辦法獲得這個功能。

          1. static是OO的大敵。可是我覺得controller靜態(tài)方法沒有什么不妥當(dāng)。它沒有什么不可測試性,你只需要提供一個mock它一樣能很好的運行。
          2.不合理的使用異常這個倒是真的,但是除了文字上的,它不應(yīng)該是一個異常之外似乎不會對系統(tǒng)造成什么問題。
          3.沒理解~~~play沒有用任何修改字節(jié)碼的手法。它有的只是借助eclipse的jdt對java文件進行即時編譯。僅僅如此而已。

          play最不好玩的地方就是它不能在標準的web容器下運行。這也許是作者有意為之的。
          java的輕不在于如何做設(shè)計,在于如何在開發(fā)人員的思想上給予一次洗禮。他習(xí)慣了有DAO,Service,習(xí)慣了返回的時候配置一個返回文件,所以你給他一個簡單的做法,他會郁悶,會奇怪,這能行嗎?萬一以后修改XX怎么辦?這是的他恨不能把所有的東西都是變成配置文件。

          另外,play的是一個python迷。所以用異常渲染頁面的辦法并非獨創(chuàng)而是來自cherrpy。controller不滿了static的方法也不是獨創(chuàng),python的web框架中很多都是如此,gae之類的甚至干脆就脫掉對象的皮就是一個函數(shù)而不是類。

          上面有朋友提到了django,這個估計在不久的將來如果不出什么意外的話,它會成為python的"java",走上一條復(fù)雜與復(fù)雜的不歸路,從此你再也不必為它龐大,臃腫,的代碼而煩惱。世界將恢復(fù)一片美好。;-)~~~

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-13 15:33 by mingj
          @pythonfly
          看來老兄對python頗有研究啊
          對python,我倒是不熟
          希望以后能有機會請教python:)

          1. play的JPAModel實現(xiàn)的機制是這樣的:
          基類里面的靜態(tài)方法(User.save)默認實現(xiàn)拋出異常,只有在子類上生命@Entity之后,play框架自動幫你的子類實現(xiàn)字節(jié)碼增強。
          其實,這個方案也是在java平臺的約束上實現(xiàn)class.save方法的無可奈何之舉,但這個過程是用戶不可控的,所以也是我比較反感的地方。

          2. java是沒有可以動態(tài)給一個對象增加一個方法的功能,而且無論如何也沒有辦法獲得這個功能。
          嗯,對的。因為java里面的class不具備ruby里面的概念,只能是修改字節(jié)碼修改默認實現(xiàn)。而這也是play的實現(xiàn)方式。

          3. 習(xí)慣了有DAO,Service,習(xí)慣了返回的時候配置一個返回文件,所以你給他一個簡單的做法
          嗯,沒錯。傳統(tǒng)的web mvc開發(fā)模式已經(jīng)限定了很多開發(fā)人員的思路,laying/iop 這些好的開發(fā)模式被僵化成為教條。但是play如果致力于消除laying/iop,那就找錯靶子了:
          1). 這些開發(fā)模式都只是形式,而不是本質(zhì),本質(zhì)是后面的分離關(guān)注點、SRP或者DIP。
          2). play開發(fā)一個簡單的domain,肯定是很順手的。但是面對復(fù)雜domain,以及團隊里面的開發(fā),這時候靜態(tài)方法、修改字節(jié)碼就成了它的軟肋了。

          所以,面對程序開發(fā)被教條化的時候,我們更多的是要考慮通過回歸OO,使用OOA/OOD來重新評估項目框架的優(yōu)劣。如何保證既提供一定的限制和約定,又提供充足的自由讓開發(fā)人員揮灑設(shè)計?
          我覺得play并沒有很好的做到這一點。

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2009-01-15 14:55 by shinewang
          @mingj
          那么,博主有什么具體的解決方法,那個rails style 的 Java web 應(yīng)用開發(fā)框架開發(fā)得怎么樣了

          # re: 看上去很美 --OOafarian對play!框架的幾點看法  回復(fù)  更多評論   

          2010-06-05 23:03 by bluegene
          controller的靜態(tài)方法在play里其實就是一個個入口,相當(dāng)于普通java程序里主類的main函數(shù),它不也是靜態(tài)的嗎,誤傷大雅啊。其實play里面最關(guān)鍵的是領(lǐng)域模型,這個可是OO的。

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 永兴县| 扎兰屯市| 西平县| 德清县| 宜丰县| 石狮市| 吴江市| 濮阳市| 林西县| 凤翔县| 中江县| 乾安县| 云梦县| 仪陇县| 麻江县| 本溪| 海林市| 嘉禾县| 横山县| 盐津县| 海丰县| 天等县| 德庆县| 修文县| 周至县| 西昌市| 镇雄县| 张掖市| 丹巴县| 铜川市| 东乌珠穆沁旗| 古蔺县| 肃宁县| 岳池县| 丰台区| 罗定市| 阳山县| 巧家县| 永川市| 大同市| 禹州市|