第7章討論過多語言編程金字塔和編程語言的三個層次,我們在圖13-1中再次重複一下。
圖13-1 多語言編程金字塔
Java位於穩定層,所以它的所有Web框架也屬於這一層。作為一門流行而又成熟的語言,Java中有很多種Web框架,比如:
- Spring MVC
- GWT
- Struts 2
- Wicket
- Tapestry
- JSF(及其他與Faces相關的類庫)
- Vaadin
- Play
- 以前那些普通的JSP/Servlet
在這一領域,Java沒有公認的領頭羊,並且源於Java的這一分支根本就不是Web快速開發的理想選擇。Struts 2曾經流行一時,該項目的前任領導者說過這樣一段話:
我墮落了:-),我現在更喜歡用Rails——因為前面提到的簡潔性,因為我再也不用「構建」和「部署」了。兄弟姐妹們,我要提醒你們,如果你們想吸引Rails開發人員......或者要避免像我這樣的「背叛Java的Web開發人員」流失:-),這類事情是你們必須克服的障礙。
——Craig McClanahan,2007年10月23日
(http://markmail.org/thread/qfb5sekad33eobh2)
本節會談到Java為什麼不是Web快速開發的理想選擇。我們先來看看編譯型語言為什麼會在開發Web應用時拖後腿。
13.1.1 Java編譯為什麼不好
Java是編譯型語言,這就是說你每次修改代碼,都必須重複下面的步驟:
- 重新編譯Java代碼;
- 停止Web服務器;
- 把改過的應用重新部署到Web服務器中;
- 啟動Web服務器。
這會浪費大量的時間!特別是有很多小修改時,比如修改控制權的目標或界面的微調。
注意 應用服務器和Web服務器之間的界限已經變得模糊了。這是因為JEE 6的出現(可以在Web容器內運行EJB),也因為大多數應用服務器都是高度模塊化的。我們提到的「Web服務器」是指任何有Servlet容器的服務器。
如果你是一位經驗豐富的Web開發人員,應該知道有些技術可以解決這個問題。其中大多數都是不用停止和啟動Web服務器就能應用代碼修改,也被稱為熱部署。熱部署或者把全部資源(比如整個WAR文件)都換掉,或者只選其中幾個(比如單個JSP頁面)資源進行替換。但熱部署不是100%可靠(因為類加載的限制和容器中的bug),並且大多數情況下,Web服務器仍然需要執行昂貴的代碼重編譯操作。
用JRebel和LiveRebel執行熱部署
如果你必須要用Java Web框架,我們強烈向你推薦JRebel和LiveRebel(http://www.zeroturnaround.com/jrebel/)。JRebel確實具備一些驚艷的JVM技巧,它處在IDE和Web服務器之間,源碼發生變化時能自動將這些變化反應到正在運行的Web服務器上(LiveRebel用於生產環境的部署)。這種熱部署基本沒什麼問題,並且這些工具實際上是解決熱部署問題的行業標準。
一般來說,Java Web框架為代碼修改而產生的周轉時間太長。但這不是唯一的問題,另外一個拖慢Web開發速度的不利因素是語言的靈活性,這是靜態類型系統的弱項。
13.1.2 靜態類型為什麼不好
在開發新產品或新功能的早期階段,保持用戶展示層設計的開放性(對於類型而言)通常都是明智之舉。對於用戶來說,要求數值精確到小數位,或讓書單變成圖書和玩具混合的清單都是非常合理的要求。靜態類型可能會成為這類需求的巨大障礙。如果你必須把一個Book
對像列表變成BookOrToy
1對象的列表,則只能在代碼中把這個靜態類型全改掉。
1 小心!如果你的域對像中有Or或And這樣的字眼出現,那你很可能違反了我們在第11章討論的SOLID原則。
儘管在容器類裡能用基本類型(比如Java的Object
類)作為對象的類型,但這肯定不是最佳實踐——這簡直是一下子回到了泛型。
因此,選擇基於動態層語言編寫的Web框架無疑是個有效選項。
注意 Scala當然是靜態類型語言。但由於其先進的類型推斷能力,它能規避很多由Java靜態類型實現方式引發的問題。也就是說,Scala可以是、也確實是可用的Web層語言。
在你繼續深入研究和選擇Web開發的動態語言之前,我們先後退一步,讓視野更開闊一點。想一想優秀的Web快速開發框架應該符合哪些標準。