讀古今文學網 > Java程序員修煉之道 > 7.3 JVM上的多語言編程 >

7.3 JVM上的多語言編程

「JVM上的多語言編程」這種說法還挺新穎的。這種說法是為了描述那些以Java代碼為核心,但還用了一種或多種其他非Java JVM語言的項目。多語言編程通常是一種關注點分離的形式。如圖7-3所示,非Java技術的作用可以分為三個層次。這張圖有時被稱為多語言編程金字塔,這要歸功於Ola Bini。

金字塔中有三個明確的層次:特定領域層、動態層和穩定層。

圖7-3 多語言編程金字塔

多語言編程的秘密

多語言編程之所以有意義,是因為不同的代碼片段有不同的生存期。銀行裡的風險引擎可能會持續運行五年以上;而網站上的JSP頁面可能只有幾個月;最短命的啟動代碼可能只「活」幾天。代碼「活」得時間越長,越靠近金字塔的底部。

它代表了不同側重點的相互折中,比如底部更關注性能和全面測試,而頂部側重的是靈活性和快速部署能力。

表7-1給出了這三個層次的更多細節。

表7-1 三層多語言編程金字塔

名稱 描述例子 特定領域層特定領域語言。與應用程序領域的特定部分結合非常緊密 Apache Camel DSL、Drools、Web模板 動態層開發速度快、生產率高、功能靈活部署Groovy、Jython、Clojure 穩定層核心功能、穩定、經過良好測試、性能高Java、Scala

這些層次中有特定的模式,靜態類型語言更傾向於穩定層的任務。相反,能力不是那麼強、通用性比較低的技術在金字塔的頂部更容易找到自己的位置。

金字塔中部給動態語言留出了很多位置。這也是最靈活的一層,大多數情況下在動態層內部或者在動態層和相鄰層之間有重疊。

我們要對這張圖繼續深挖,看看Java語言為什麼不是金字塔所有層次的最佳選擇。接下來我們先來看看為什麼要考慮非Java語言,然後給出一些選擇非Java語言的重要標準。

7.3.1 為什麼要用非Java語言

Java作為一種通用、靜態類型的編譯型語言有很多優勢。這些品質使它成為實現穩定層功能的絕佳選擇。但同樣的特性放到金字塔上層就會變成負擔。比如說:

  • 重新編譯太費工了;
  • 靜態類型不夠靈活,重構起來時間可能會比較長;
  • 部署的動靜太大;
  • Java的語法天然不適用於生產DSL。

Java項目重新編譯的時長迅速攀升到了90秒到2分鐘。這個長度足以嚴重打斷開發人員的思路,並且對於只在生產環境中存活幾個星期的代碼來說,這種開發方式太糟糕了。

比較務實的辦法是利用Java豐富的API和類庫完成穩定層的繁重工作。

注意 如果你剛開始一個新項目,可能會發現其他穩定層語言(比如Scala)也具備非常重要的特性(比如卓越的並發支持)。然而在大多數情況下,不應該用其他種類的穩定語言重寫正在使用的穩定層代碼。

這時你可能會納悶:「每一層都會面臨什麼樣的編程挑戰,我該選哪種語言?」一個優秀的Java開發人員知道,根本沒有所謂的銀彈,但當我們面對選擇時,的確有一定的評估標準。我們不可能在這裡把每個可能的選項都討論到,所以在剩下的章節中,我們會集中討論三種大多數Java開發人員可能都會面臨的選擇。

7.3.2 嶄露頭角的語言新星

接下來我們會挑三種,在我們看來可能最有生命力和影響力的語言。這些JVM語言(Groovy、Scala和Clojure)在多語言程序員心目中已經有了相當的份量。這三種語言為什麼會得到大家的青睞?且聽我們一一道來。

1. Groovy

Groovy語言是James Strachan在2003年發明的。它是動態的編譯語言,語法跟Java很像,但更靈活。它被廣泛用做腳本語言和快速原型語言,並且經常是開發人員或團隊首選的非Java語言調研對象。你可以把Groovy看做是動態層的語言,它以擅長構建DSL著稱。第8章主要介紹Groovy。

2. Scala

Scala是一門面向對象的語言,但也支持函數式編程。它的起源可以追溯到2003年,當時Martin Odersky正在用Java做一個與泛型相關的項目,結果卻催生了Scala。它和Java一樣,是靜態類型的編譯語言,但和Java不同,它做了大量的類型推斷工作。也就是說它經常給人以動態語言的感覺。

Scala從Java中借鑒了很多東西,並且它的設計「修正」了Java中幾個長期以來困擾開發人員的問題。Scala可以做穩定層語言,並且有些開發人員認為它可能會取代Java成為「JVM上的下一個大語言」。第9章介紹Scala。

3. Clojure

Clojure是由Rich Hickey設計的,屬於Lisp家族的語言。它從Lisp中繼承了很多語法特性(包括大量的括號1)。就像大多數Lisp語言一樣,它是動態類型的函數式語言。它是編譯型語言,但通常以源碼形態發佈(稍後解釋)。Clojure還向它的Lisp核心中添加了相當可觀的新特性(特別是在並發方面)。

1 Lisp的表達式是一個原子(atom)或表(list):原子(atom)又包含符號(symbol)與數值(number);表是由零個或多個表達式組成的序列,表達式之間用空格分隔,放入一對括號中。此處的括號應該是指內置的表達式。——譯者注

Lisp通常被當做專家語言。Clojure在某種程度上來說要比其他Lisp語言容易掌握,然而這並不會影響其強大的力量(也非常適合測試驅動的開發風格)。但它可能還是徘徊在主流之外,只是狂熱的愛好者手中的秘密武器,抑或遇到適合它的特殊工作才發光(比如有些金融應用程序發現它的功能組合非常有吸引力)。

Clojure通常被認為是動態層的語言,但由於它的並發支持以及其他一些特性,也能勝任很多穩定層語言的工作。第10章會重點介紹Clojure。

現在我們已經把可選擇的一部分語言羅列出來了,接下來該討論一下決定你做出選擇的那些因素了。