search
尋找貓咪~QQ 地點 桃園市桃園區 Taoyuan , Taoyuan

以Java、Kotlin和Scala編寫基本Spring Web應用的比較

現在可以用來開發web應用的語言五花八門,每種語言都各有千秋,本文作者挑選了Java、Kotlin 、Scala這三種語言,開發同一個基礎的Spring web應用,從而比對出他們之間的差別。

我一直在想,在JVM語言中選擇一個(如ScalaKotlin)用來實現同一個基礎的Spring Boot應用程序是多麼的困難,所以我決定試試。

源代碼可以這個地址看到:

這款應用程序是非常基礎的,因為它只包含以下元素:

  • 兩個資料庫實體

  • 兩個Repository註解

  • 兩個controller控制器

  • 六個endpoint

  • 一個虛擬的靜態的index頁面

我將用三種語言來做代碼比較:

實體

這個應用裡面涉及到了兩個實體:Customer和Pet

Java

這裡無需多言——因為很顯然Java是很冗長的,即使去掉getter和setter方法之後,還是會有很多的代碼。除了使用Lombok可以幫助用戶生成模板文件以外,或者類似的工具,我們也沒有什麼更好的辦法。

Kotlin

在Kotlin語言中有好幾種方法可以定義一個實體類,我已經試過兩種了。儘管作用都是一樣的,但是後者可能更受用戶歡迎,因為前者只是簡單地在做一些Java裡面也能做的事情。

儘管第一眼看上去,它不像Java代碼那樣比較直觀,但是用數據類實現的話,代碼量就要短得多,而且也不需要大量的模板文件。這裡的大部分冗餘代碼都是因為需要做必要的註釋。

注意,實體類需要一個默認的沒有參數的構造函數——它在常規類的情況下顯式提供,而數據類通過為單個構造函數中的每個參數定義默認值來提供的 - 包括一個默認值,而沒有參數,它只是將默認值分配給每個變數。

由於需要將override關鍵字顯示的定義出來,這樣做代碼更容易閱讀,出現錯誤的概率也會降低,所以我挺喜歡這種做法的。

Scala

實際上僅針對這種情況,我對Scala感到失望——它的實現幾乎和Java一樣冗長,它們的區別就在於Scala不需要顯示的定義好getter和setter方法,它只需要使用額外的欄位註釋(@beanproperty)就可以了。

我試圖使用一個case class來減少代碼實現的行數,這在理論上是可以行的通的,但是我不能讓它運行起來(也許這根本原因就是因為我使用Scala不熟)。

至少它提供了字元串插值(String interpolation),允許在一行中使用大括弧,並且需要顯式的override關鍵字,這與Kotlin是一致的。

Repositories

Java

注意,findByLastName函數實際上並沒有在其它地方進行調用,我定義它只是用來提供一個示例的。

Kotlin

這裡沒有太大的區別,代碼基本上是一樣的。Kotlin版本的代碼稍微短一點,這是因為Kotlin的默認修飾符是public的,而且有一個:符號而不是extends關鍵字。此外,也有可能是如果沒有在body中定義任何內容的話,就有可能可能會忽略花括弧。

Scala

Scala使用的是traits,而不是interfaces,但在大部分情況下它們都是相同的概念,或者至少針對我們這個簡單的例子而言它們是一樣的。

由於某些原因,需要將Long類明確定義為java.lang.Long以避免編譯錯誤(我再次對Scala感到失望)。

Controllers控制器

Java

Scala

CustomerController是通過構造函數注入的,而PetController則是通過欄位注入的,這麼做是為了提供出兩種不同的方式——Kotlin和Scala也是同樣的處理邏輯。

同樣,Java的話,代碼還是顯得很冗長,儘管其中很大一部分來自於健壯的註釋(使用@get/PostMapping代替@requestmapping來減少註釋的大小)。值得注意的是,Java 8將會解決這個問題,因為由於缺少lambda函數,getAllCustomersFormatted函數在Java 7中會變得更加臃腫。

Kotlin

乍一看,這似乎和Java一樣冗長,這很讓人吃驚,但我們必須注意到,這種冗長的代碼大部分來自於所需的註釋。除去這些,控制器的主體僅僅只有4行。

當然,如果我要將@requestmapping註釋寫在一行中,那麼它就不會那麼簡單了,但是在博客文章中,可讀性就會首先出現。

使用@get/PostMapping註釋可以讓我們至少跳過方法參數,以減少註釋的大小。理論上,我們可以去掉produces和consumes,但這也會使XML成為一個可行的選擇——所以這些params並不是多餘的。

需要指出的一件令人討厭的事情是,如果需要使用多個參數(除了默認值以外),那麼在註解中使用arrayif是必要的。這將在Kotlin 1.2中得到修復

我喜歡這個構造函數注入芬蘭灣的科特林提供了(我們甚至不需要一個@ autowired註解出於某種原因[這是原因])雖然看起來令人困惑如果類更大,更依賴項注入,我想說這是一個機會,在這種情況下適當的格式。

Scala

Scala還需要在提供參數時使用Array關鍵字,即使是默認的參數也需要。

getAllCustomersFormatted函數,這是一種暴行,但我不能讓Java集合正確地使用Scala集合——所以,對不起,我的眼睛(划痕,代碼在Teemu Pöntelin的幫助下得到了改進,謝謝:))。

請注意,必須在構造函數中包含@autowired,這可能在Kotlin中跳過(如果您只有一個構造函數,那麼實際上根本不需要@autowired),如這裡所解釋的那樣)。

總結

儘管這個應用程序非常簡單,但是對於我來說,這足以讓我對如何在每一門特色語言中做一些更深入的了解有一個基本的感覺。

如果需要在 Kotlin 和 Scala 之間做個選擇,毫無疑問我的選擇是Kotlin

為什麼呢?

首先,我覺得Scala就好像是IntelliJ IDEA中的二等公民一樣,而Kotlin無疑是一等公民。這是顯而易見的,因為創建IDE(Jetbrains)的公司和創建Kotlin語言的公司是同一家的——所以他們當然非常支持這門語言。另一方面,Scala是通過一個插件集成的。兩者的區別是顯而易見的,至少對我個人來說,這種區別是非常重要的。

其次,如果我想用Scala為web應用程序開發框架,我就會選擇 Play Framework,原因很簡單,就是因為它設計的思維是基於Scala 的,而且開發語言能使得某些事情變得更容易,而不是妨礙你(就像在這個小應用程序的情況下)。

這些都是我個人的原因,但也有更多、更普遍的原因。

我覺得Scala比Kotlin更脫離Java,因為後者基本上算是一種擴展,旨在解決Java最初存在的問題,而前者的目標是將命令式編程和函數式編程混合在一起。儘管如此,我相信Scala在其他領域更好地使用,比如大數據,而Kotlin在它應該做的事情上做得很好——取代Java解決一些比較常見的問題,並提供緊密的互操作性。

此外,Spring本身似乎對Kotlin 的支持遠遠超過了對 Scala的支持。

最後,我相信,從Java程序員的角度來看,Kotlin比Scala更容易學習。這主要是因為Kotlin被設計為基於Java進行的改進,並沒有像Scala那樣重視函數式編程。在Kotlin中,與Java的互操作性也更加緊密,這使得調試問題更加容易。

最後,但同樣重要的是——我想明確地聲明我不會以任何方式抨擊Scala。就我個人而言,我認為 如果用一門非Java的JVM 語言去開發一個Spring Boot的web應用程序——Kotlin會是更好的選擇。粗體部分是很重要的:)正如前面提到的,在其他領域,Scala是很優秀的,比如前面提到的大數據,但想要取代Java目前估計還有一段很長的路要走。



熱門推薦

本文由 yidianzixun 提供 原文連結

寵物協尋 相信 終究能找到回家的路
寫了7763篇文章,獲得2次喜歡
留言回覆
回覆
精彩推薦