OOPAA

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


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

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


          評(píng)論

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

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

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

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

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

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

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

          能詳細(xì)比較一下django和play么?

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

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

          一個(gè)很新穎的框架。

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

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

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

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

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

          2009-01-03 11:01 by mingj
          @hcom
          這個(gè)倒沒有研究
          因?yàn)槲抑皇窍胙芯坷锩嬉恍┍容^新穎的東西和想法

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

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

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

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

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

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

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



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 武威市| 深州市| 随州市| 孟州市| 余庆县| 南昌市| 云南省| 建湖县| 兴义市| 榆林市| 彭水| 凤台县| 宁海县| 开平市| 邻水| 玉林市| 贵溪市| 宁德市| 马鞍山市| 武平县| 达拉特旗| 沙雅县| 石渠县| 黔江区| 金溪县| 杂多县| 措勤县| 衡阳市| 海盐县| 利川市| 两当县| 仪陇县| 宜兰县| 大安市| 达孜县| 台南市| 普陀区| 长宁区| 大余县| 桐城市| 赣州市|