Picses' sky

          Picses' sky
          posts - 43, comments - 29, trackbacks - 0, articles - 24

          轉(zhuǎn)自:http://blog.csdn.net/koalant/archive/2006/06/26/836889.aspx

          最先發(fā)表于 http://www.5dblog.com/vip/mulder/200604/246313.html


          Howard Lewis Ship

          我做Java編程大概有四年了,但我仍然處在從Java初級程序員向中級程序員過渡的階段。 Java 包含的東西實在太多,三大體系 J2ME,J2SE,J2EE 每個都包含了大量的內(nèi)容,身為一個 Java 程序員其實挺悲哀的,不僅要不停地學(xué)習(xí)那么多基礎(chǔ)知識,還要應(yīng)付層出不窮的框架。不光要學(xué)理論,還要注重實踐。想想原來搞 Perl, PHP 的時候,哪來的那么多知識點。雖然我的Java水平不高,但我始終對要學(xué)的東西保持自己的看法,對于技術(shù)我總是抱著懷疑一切的態(tài)度,有時候甚至很固執(zhí),就算我是錯的,我也要自己撞了南墻來體驗。我的觀點是:"好話左右不了我,我會自己判斷的。大家都說好,我可能偏不喜歡"。

          我曾經(jīng)在編程技術(shù)上做過四次選擇:
          1:選擇了 Velocity ,放棄了 JSP.
          2: 選擇了 Ruby ,放棄了 Python.
          3: 選擇了 Hivemind, 放棄了 Spring.
          4: 選擇了 Intellij, 放棄了 Eclipse.

          四年前第一次接觸 Java WEB 編程的時候,我沒有選擇學(xué)習(xí) JSP ,而是選擇了 Apache 的 Velocity 框架。當(dāng)時的 freemarker 也是相同類型的模板引擎,它甚至可以在模板中使用 JSP 的Taglib,我仍然選擇了 Velocity ,因為我覺得視圖層并不需要那么復(fù)雜。 Velocity 框架很簡單,模板語言只負(fù)責(zé)簡單的顯示邏輯處理,速度更快,沒有 JSP 第一次編譯的速度延遲,而且它是一個通用的模板引擎,不光用于 Web 開發(fā),如今它還被用在了 Intellij 中做為代碼生成的工具。Freemarker 在模板中使用 Jsp Tag 的功能在我看來是個累贅,使得本來簡單的東西添加了復(fù)雜性,所以我沒有選擇它。JSP 從一開始設(shè)計就是錯誤的,它沒有及時避免出現(xiàn)失控的情形(頁面中充斥 Java 代碼,這就類似于 C++ 沒有從一開始避免程序員寫 C 那樣的過程代碼一樣。而且 Taglib 也不是一個好的擴展顯示邏輯的方式。

          我在接觸 Java 前曾經(jīng)使用過一段 Zope 和 Python ,即便是在使用了 Java 兩年后,我仍在研究 Zope 和 Python 。 使用 Python 這樣的腳本語言主要是為了編寫一些Java代碼生成工具。如果用 Java 來寫這種工具,無論編寫還是發(fā)布都顯得不那么完善。腳本語言最擅長是處理文本字符,文件,它們通常內(nèi)置正則表達(dá)式功能,這些都成了編寫Code generator 的強有力的工具。 Zope 建立 Web 站點的能力是有目共睹的,相對 Java 來說,它的開發(fā)效率更好,雖然執(zhí)行效率較低,但是滿足大多數(shù)中小規(guī)模網(wǎng)站的制作。接觸了 Ruby 后,我逐漸離開了 Python。 原因是 Ruby  在編程中給我了一種從未有過的快樂感。我曾經(jīng)認(rèn)為 Python 的縮進(jìn)語法是它的優(yōu)勢,因為這種強制性使得代碼的可讀性大大的增強了,即便是多年之后再看自己寫的代碼,或者是別人寫的代碼,你還是很容易讀懂。但是 Python 語言本身的一些弱點,使得你感覺很不舒服,它的面向?qū)ο蟛粡氐祝皇蔷邆湟恍?OO 的特點,使得在使用它的時候有點四不象的感覺。如果你用過 Ruby 這種感覺會更加強烈。不過這種選擇取決于你是否是一個“面向?qū)ο缶幊?#8221;的強烈愛好者,否則 Python 長期積累的現(xiàn)成的成熟代碼庫會使得你很容易的選擇它的。我想對我個人編程影響最大的一本書,當(dāng)屬 Dave Thomas 的那本 "Programming Ruby"的電子版了。通過它我才得以系統(tǒng)地學(xué)習(xí)了 Ruby ,并把我以前用 Python 寫的腳本程序全部替換為 Ruby 腳本。直到現(xiàn)在,文件操作和數(shù)據(jù)庫備份移植的腳本文件我都采用 Ruby ,而這些操作如果用 Java 來寫,復(fù)雜性可想而知 。所以我一直認(rèn)為一個程序員至少應(yīng)該掌握一種腳本語言,并非為了學(xué)習(xí)腳本語言而學(xué)習(xí)它,主要是為了讓自己的編程工作更輕松一點。至于后來放棄 Zope 而選擇 ROR ,就是再自然不過的事情了。

          Spring 的流行其實應(yīng)該算是 Java 世界反對 Sun EJB 技術(shù)的一個必然結(jié)果,就算不是 Rod Johnson 推出 Spring 框架,大家也必然會采用另外一個人推出一個基于 POJO 的 IOC 容器框架的。其實在那個時候推出了很多 IOC 容器框架,比如 Pico Container, 還有那生不逢時的 Avalon,這些框架都或多或少有些問題。Pico 只是個簡單的 IOC 容器,功能相對較弱。Avalon 不僅僅是個 IOC 容器,它更是一個組件框架。但是它是 type-1 型的框架,也就是說它是基于接口的服務(wù),它的缺點是你必須實現(xiàn)一個特定的接口,這就造成了對特定框架的依賴性。早期的容器采用這種方式有其歷史原因,后來推出的 IOC 容器不是采用 type-2(Setter)設(shè)置屬性的方式來設(shè)置依賴關(guān)系,就是采用 type-3 (constructor) 構(gòu)造函數(shù)的方式來設(shè)置依賴關(guān)系。Spring 和 Pico 就是如此,雖然兩者都同時支持 type-2 和 Type-3 ,但是 Spring 更多使用 Setter 設(shè)置依賴關(guān)系,而 Pico 習(xí)慣采用構(gòu)造函數(shù)。現(xiàn)在很多人都夸大 type-1 型這種接口依賴性的缺點,認(rèn)為這是過時的框架(事實上 Avalon 框架最終被 Apache 組織放棄了)。 其實我并不這么看,我們公司使用  Avalon , Cocoon 框架很多年,對于一個多年使用 Avalon 框架的用戶, 對過去代碼的依賴性可能使得它不會簡單地拋棄它,Avalon 組件式開發(fā)方式有其優(yōu)勢,在部署的時候有極大的好處,這點我在后面談到 Hivemind 的時候詳細(xì)再說。必須繼承某個框架的特定接口,會使得將本框架代碼移植到新框架的時候出現(xiàn)依賴性問題,但是如果你不存在更換框架的可能性的話,使用這種 Type-1 型框架就沒有什么太大的缺點了。人們總是喜歡設(shè)置假想的未來預(yù)期,比如盡量少用數(shù)據(jù)庫存儲過程,因為這樣產(chǎn)生數(shù)據(jù)庫移植的困難,事實上真正企業(yè)級的項目很少會更換數(shù)據(jù)庫層的,這點Rod Johnson 在他那本名著《Expert One-on-One J2EE Design And Development 》的第一章就做了闡述。所以對 Type-1 型框架的恐懼也是沒道理的。 如果你已經(jīng)在使用這樣的框架,那么就堅持繼續(xù)使用它,它的成熟性可能會給你帶來更大的開發(fā)益處,但是如果你是個新手,那么最好還是采用 2 和 3 型的框架,能避免依賴性的時候還是應(yīng)該盡量去做。

          Spring 現(xiàn)在可以被看作是一個 FullStack 的全功能性框架,它不象 Struts 那樣僅僅是個簡單的 MVC 視圖層框架,它包含了對 J2ee 開發(fā)各個方面的支持。在接觸  Spring 框架之前,我就通過閱讀 Rod Johnson 的 Expert One-on-One J2EE Design And Development 獲益非淺,書中的各種真知灼見對任何一個開發(fā)者都有很大的啟發(fā),即便他不采用 Spring 來開發(fā)自己的應(yīng)用。現(xiàn)在看來 ,Spring 在 Java 語言層次上已經(jīng)做到了盡可能的簡化和正確的決策。隨著對它的了解日益加深,我發(fā)現(xiàn)它存在一些問題。大家都說 Spring 的XML配置文件太多了,其實我并不這么認(rèn)為。看看 Hivemind ,Avalon 這些流行框架,哪個 XML都不少,這是 Java 框架的通病。 Spring 有一個優(yōu)秀的 IOC 容器,它容納的是 POJO ,但是它并沒有發(fā)展成為一個組件框架。Rod Johnson 說"面向?qū)ο蟊饶承┘夹g(shù)本身更重要",Spring 也是這么做的,使用它你可以容易的面向接口編程,但是面向?qū)ο缶幊谈嫦蚪M件編程是兩個階段,面向?qū)ο笾饕窃陂_發(fā)階段,而面向組件編程,更關(guān)注于部署 Deploy 階段的工作。 一個面向組件的框架要考慮更多的動態(tài)部署的問題。 Spring 的問題出在部署上,如果你用過 Avalon 和 Hivemind, 你會覺得它們那種通過替換 Jar 包來更新功能的方式真的很爽,而這種特點在 Spring 中卻看不到。 在 Spring 編程中,你會看到清晰的分層:表現(xiàn)層代碼,應(yīng)用層代碼,數(shù)據(jù)持久層代碼,它們各司其職,靠的是XML 配置文件來描述各層代碼之間的依賴關(guān)系。所有這些代碼和 XML 配置文件是放在一起的,Spring 應(yīng)用的部署就是一種 "All or Nothing "的局面,更新一小段代碼, 你就要更新整個應(yīng)用的部署.如果采用 Avalon 或 Hivemind 這樣的組件框架, 優(yōu)勢就明顯了. 使用這樣的組件框架來開發(fā)應(yīng)用, 通常將程序員分類兩類: 組件或服務(wù)開發(fā)者(系統(tǒng)程序員), 應(yīng)用程序員. 系統(tǒng)程序員負(fù)責(zé)開發(fā)組件或者(服務(wù)), 供應(yīng)用程序員調(diào)用. 舉個例子, 如果要開發(fā)一個網(wǎng)頁計數(shù)器的應(yīng)用, 我可以將計數(shù)器的功能先定義接口 Counter,然后提供默認(rèn)實現(xiàn), 如果你采用文件來記錄計數(shù)器的數(shù)值,可以提供一個 CouterFileImpl 的實現(xiàn)類, 如果采用數(shù)據(jù)庫來記錄數(shù)值,那么可以提供一個 CounterDBImpl 的實現(xiàn)類. 這種服務(wù)的概念,將原來的應(yīng)用開發(fā)三層的概念(表現(xiàn)層,應(yīng)用層,數(shù)據(jù)持久層)簡化為兩層(應(yīng)用層,服務(wù)層), 原來的表現(xiàn)層對應(yīng)應(yīng)用層,由應(yīng)用程序員開發(fā), 而原來的應(yīng)用層和數(shù)據(jù)持久層對應(yīng)服務(wù)層,由系統(tǒng)程序員開發(fā). 現(xiàn)在流行的各種表現(xiàn)層框架雖然是按照 MVC 模式設(shè)計的, 但是大多只是實現(xiàn)了 VC (視圖和控制器),而對于M(模型)并沒有提供什么支持. 以前這些框架多是推薦采用 Session Bean 來實現(xiàn)模型(M), 但是隨著Spring 等POJO IOC 框架的流行, 模型的實現(xiàn)可以采用 Spring POJO , 和Avalon, Hivemind 服務(wù)來替代實現(xiàn). 應(yīng)用程序員可以采用任何流行的表現(xiàn)層框架來獲取這些服務(wù)完成顯示的任務(wù). Spring 的問題出現(xiàn)在這里: Spring不是組件框架,沿襲原有的三層的概念, 是以 XML 來組織所有三層代碼. 如果要改任何一層的代碼,就牽扯到整個代碼同時更新和部署. 其實這個問題還是可以通過 Maven 將不同包編譯為 Jar 來解決, 但這不如組件框架直接提供這樣的服務(wù)好. 如果采用 Hivemind ,可以將服務(wù)接口和對應(yīng)服務(wù)實現(xiàn)編譯為 Jar 包, 接口可以定義在一個Jar 包中, 不同的實現(xiàn)也可以定義在不同的 Jar 包中, 當(dāng)然接口和所有的實現(xiàn)也可以都放在一個 Jar 包中. 這樣如果后臺實現(xiàn)變化了(文本記錄改為數(shù)據(jù)庫記錄),那么系統(tǒng)程序員只要提供一個新的Jar(可以只更新Jar中的配置,修改默認(rèn)實現(xiàn)的指向)給應(yīng)用程序員, 這個修改部署就是以Jar包為最小單位.它的簡單性是 Spring 提供不了的. 如果你看過 Howard Lewis Ship (Tapestry 和 Hivemind 框架的創(chuàng)始人)的日記, 就會知道他曾經(jīng)在多年前闡述過這個問題, 并就此跟 Spring 框架的創(chuàng)始人 Rod Johnson 在多個研討會上交流過,無奈 Rod 有自己的觀點, 沒有接受 Howard 的意見, 所以才有了后來 Hivemind 框架的問世. Spring 鼓勵程序員采用面向?qū)ο笏枷?面向接口編程, 但是沒有針對面向組件提供幫助. 面向組件編程更多的是考慮部署的概念, 如何從當(dāng)前應(yīng)用的類路徑中動態(tài)找尋一個類,類路徑下存在一個類的多個版本,應(yīng)該如何確定加在的版本等等. 擁有組件框架對于應(yīng)用程序開發(fā)者來說有極大的好處, 無論采用什么表現(xiàn)層框架,它都可以輕易的調(diào)用服務(wù), 對它來說, 后臺應(yīng)用邏輯的更新, 持久層的更換也只是一個Jar包替換的問題. 如果表現(xiàn)層框架換了, 調(diào)用現(xiàn)有服務(wù)也是很容易的. Spring 基本上是采用XML來描述各個POJO 之間的依賴關(guān)系, 通過 Setter 或 Constructor 注入. 我覺得"在表現(xiàn)層依然采用 IOC 注入方式" 也是一個問題, 如果采用 Hivemind , 使用 Struts 做表現(xiàn)層,你可以通過 Service Locator 的方式獲得服務(wù), 而采用 Tapestry 你也可以采用 IOC 方式注入 Hivemind 服務(wù). 這樣對應(yīng)用程序開發(fā)人員來說就非常靈活了. 所以我推薦大家采用 Hivemind 這種新型的 IOC 組件框架來開發(fā) Java web 應(yīng)用.

          我發(fā)現(xiàn)大多數(shù)使用 Java 一兩年的程序員都喜歡構(gòu)造自己的"完美"組合開發(fā)框架, 我也是如此. 不過這方面做的最"過分"的當(dāng)屬 Matt Raible , 這位仁兄創(chuàng)建了 Appfuse 這個Starter 框架, 它結(jié)合了當(dāng)今所有流行的框架加以組合來開發(fā)一個簡單應(yīng)用. 當(dāng)初只是一個實驗性的模型, 新的版本已經(jīng)非常復(fù)雜了. Appfuse 也是采用三層組合,每層中都采用最流行的框架, 不過相對來說, 應(yīng)用層和數(shù)據(jù)持久層采用的框架比較穩(wěn)定,就是 Spring 和  Hibernate , 最近數(shù)據(jù)持久層又添加了 iBatis 和 JDO, 不過最豐富的當(dāng)屬表現(xiàn)層了, 當(dāng)今主流的 Web 框架,他用了一遍, Webworks, spring mvc, struts, tapestry, jsf . 其實 Matt 現(xiàn)在做的有點過頭了, 我承認(rèn)我自己也是通過學(xué)習(xí)他的 Spring Live 一書來了解 Spring 開發(fā)的. 我對他那個相對簡單的 equinox (Appfuse Light 版本)框架更感興趣一點, 現(xiàn)在的 Appfuse 對我來說,已經(jīng)膨脹到無法看下去的地步了.  其實他如此組合沒有什么太大的意義,最終程序員都會有自己的"完美"方案的. 我的選擇是 Spring MVC + Hivemind + Hibernate . 以前中間應(yīng)用層我是采用 Spring , 因為 Spring 和 Hibernate 的結(jié)合比較完美, Template 的確簡化了代碼量,使用也很簡單. 但是隨著 Hibernate 3.x 的推出, 原有的 Checked Exception 都改為 Unchecked Exception 了, 使用 Spring 的優(yōu)勢就不那么明顯了, 而組件框架部署的優(yōu)勢就成了首先考慮的問題. Spring MVC 是 Spring 框架中一個從頭開發(fā)的子框架, 它的設(shè)計比較完善,功能很多: 多視圖層輸出, 向?qū)ы撁娴鹊? 如果你采用Flash 來制作 RIA 應(yīng)用就可以采用 Velocity做視圖層生成 XML 數(shù)據(jù), 也可以利用 Spring 的 Webservice 集成功能. 這是我心目中一個完美的組合.

          現(xiàn)在還有不少人正在繼續(xù)構(gòu)造自己“完美”的框架,其實這種追求完美的過程是永無止境的,正如那個廣告中說的“沒有最好,只有更好”。記得以前看《六人行》第一季中有這么一集,Chandler 公司的一個女同事說要給他介紹一個“完美”的男友,Chandler 說了這么一句話 “Ah, y'see, perfect might be a problem. Had you said 'co-dependent', or 'self-destructive'”,當(dāng)時我并沒有理解這句話的意思,現(xiàn)在覺得這似乎是描述這種追求完美框架行為最合適的一句話了。我想,可能有不少Java程序員跟我一樣,打算尋找一個最完美的組合框架來做一個自己的應(yīng)用,結(jié)果這個應(yīng)用過了一兩年都沒完成。Java 程序員過于重視理論上完美的設(shè)計,而忽略實際的效果。看看如此眾多的 Java 框架竟然構(gòu)造不出一個好的論壇程序,所有出色的論壇都是出自 PHP 和 PERL,的確很 讓 Java 程序員羞愧的。現(xiàn)在看來,真正的 Pragmatic Programmer( 實用主義程序員)都來自這些腳本語言的使用者,他們沒那么多思想包袱,是真正篤信“實踐出真知”的一群人, Java 社區(qū)應(yīng)該多向他們學(xué)習(xí)。對于 Java 程序員來說,關(guān)鍵不在于你是否尋找到一個完美的框架組合,而是要做出一個好的應(yīng)用。在論壇與人空談,與人論戰(zhàn)是沒有任何意義的, David Heinemeier Hansson 建立 Rails 是在做項目的過程中產(chǎn)生的,他沒有采用任何已有的框架,也沒有去和別人辯論,而是靠實事說話把整個 Java 業(yè)界攪的天翻地覆。 我想這點值得廣大 Java 程序員深思。

           

           程序思考【寫在辭職在即】:1:“主動程序員”vs“被動程序員”

          http://blog.csdn.net/koalant/archive/2006/06/26/836882.aspx

          Feedback

          # re: 【程序思考】 關(guān)于“框架”[zz]  回復(fù)  更多評論   

          2007-07-24 10:52 by Matthew Chen
          編程講究思想,思想提倡oo,oo要求復(fù)用,復(fù)用終將不用。
          我仍舊喜歡Java,也許是還沒怎么接觸其他語言吧。
          如果有一天...
          主站蜘蛛池模板: 林周县| 樟树市| 银川市| 随州市| 苏尼特左旗| 师宗县| 聂荣县| 寻乌县| 蓬安县| 磴口县| 通山县| 马公市| 东辽县| 盐源县| 正定县| 遂昌县| 邓州市| 沂源县| 榆树市| 镇赉县| 葫芦岛市| 彰武县| 壶关县| 基隆市| 邳州市| 通许县| 遵化市| 华坪县| 湘乡市| 龙井市| 扎兰屯市| 灵丘县| 鄢陵县| 二手房| 简阳市| 昌黎县| 嵊州市| 仙桃市| 大关县| 观塘区| 吉木乃县|