Scala不是更好的Java
當人們談論Scala的使用經驗時,經常說可以將Scala看作是更好的Java。許多公司特別是在2008-2009年間採用Scala的公司,並不想放棄Java等熟悉的工具,而只是將Scala整合到基於Maven的現有工作流程中。然而現在已經不再這樣了。在大多數情況下,當代Scala技術棧再也不使用Maven作為構建工具,不使用Spring作為DI容器,很少使用傳統的設計模式。那麼他們使用什麼?
依賴注入
可以說最流行的Scala Web框架是Play,當它剛剛出來時,它沒有提供任何基礎設施以實現DI。2.4版本提供了將Google Guice一起作為一個折中的DI解決方案。不是在Scala世界的每個人都非常渴望重回Java註釋的,幸運的是,這其實也沒有必要。使用Play框架,總是可以用另一個執行時解決方案替換Guice,或者使用一個完全不同的路由並使用所謂的編譯時(compile-time)依賴注入。
使用編譯時(compile-time)DI,能讓服務類接受較低階別的依賴作為建構函式的引數。在Scala中,建構函式引數可以以常規方法訪問,所以大多數時候,這些服務可能是完全無狀態的。這種方法也被幾個Java(和.NET)專家提倡,但它絕不是主流。有趣的是,Scala開發人員比Java / C#使用者有優勢,因為他們可以透過將基於宏的庫與延遲定義組合來實現簡化:
// trait AppComponents lazy val userDao = wire[UserDao] lazy val sessionDao = wire[SessionDao] lazy val userService = wire[UserService] lazy val authService = wire[AuthService] <p class="indent"> |
上面的例子使用了一個來自MacWire庫的函式wire。在編譯階段,此函式將分析每個類並呼叫其建構函式,同時將已初始化的服務作為引數傳遞。此外,使這些值延遲確保編譯器而不是開發人員在將來負責初始化順序。
毫不奇怪,這種方法在近年來變得非常流行,並且使得Play小組考慮將其作為在即將到來的版本的框架中的預設做法。
資料庫訪問
開發的另一個典型方面是與資料庫互動。當Java第一次出來,很高興看到一個查詢資料庫語言能夠開箱即用。然而,使用純JDBC會編寫很多程式碼樣板,因此主流Java方法是使用ORM。
當使用ORM時,通常建立領域類並註釋它們以描述類如何對映到資料庫模式。作為回報,ORM為您提供簡單的方法來持久化和檢索域物件,同時自動執行物件關係對映。這種方法在理論上肯定看起來很高大上,但在實踐中,它導致了許多問題。來自Java社群的一些人指出,手動編寫純SQL實際上要比依靠ORM生成必要的語句更好。最突出的例子是名為jOOQ的庫,它允許開發人員使用Java方法編寫型別安全的SQL程式碼:
create.selectFrom(BOOK) .where(BOOK.PUBLISHED_IN.eq(2011)) .orderBy(BOOK.TITLE) <p class="indent"> |
然而,這種方法在Java中並不常見,而這個特定的庫質量不是很高。所以大多數人繼續使用ORM。
有趣的是,ORM從未真正在Scala中大幅度使用。似乎沒有人需要它。用於處理資料庫的最流行的Scala庫是ScalikeJDBC,Slick,Quill。所有這些都更類似於jOOQ而不是Hibernate。同樣,Scala使用者比他們的Java同事更有優勢,因為大多數這些庫嚴重依賴於Java中不存在的Scala特性(宏,隱式引數,字串插值)。
考慮以下使用ScalikeJDBC的示例:
// class UserDao def getUser(userCode: String): Try[Option[User]] = Try { NamedDB('auth).readOnly { implicit session => sql"select * from users where user_code = $userCode". map(User.fromRS).headOption().apply() } } <p class="indent"> |
程式碼可能看起來好像它容易遭受SQL隱碼攻擊,但實際上它不是:SQL字串在後臺轉換為型別安全PreparedStatement。該getUser方法還使用一些Scala特性 - 即Try和Option- 更好地預期的結果型別。我已經解釋瞭如何使用表示式組合monadic結構使您的程式碼更清晰,但重要的是,Java中沒有人這樣做,因為語言不支援。
JSON序列化
在Java中序列化和解析JSON的最流行的庫是Jackson。Jackson被包括為許多(可能是大多數)與JSON相關庫中的低階依賴,幾乎每個人都廣泛使用。Jackson使用反射API對映欄位,但預設行為可以透過註釋進行調整:
public class Name { @JsonProperty("firstName") public String _first_name; } <p class="indent"> |
因為Java世界中的一切都圍繞著JavaBeans的概念,預設情況下,Jackson假定你的類包含私有的可變欄位和getter / setter等方法來訪問/改變內部欄位。有趣的是,Jackson還包含一個子專案jackson-module-scala。它絕對也有使用者,但我的經驗表明,大多數Scala開發人員喜歡使用別的東西。
Scala有幾個開發JSON庫,大多數不是基於反射。讓我們來看看最流行的一個 - play-json。
在Scala中,通常不會讓您的資料類可變。因此,你建立一個case class並使其不可變:
case class Tag(id: UUID, text: String) <p class="indent"> |
如何將它序列化為JSON?這很簡單!只需新增一個隱式的型別值Writes:
object Tag {
implicit val writes = Json.writes[Tag]
}
就是這樣!你不需要實現特殊的標記介面或在任何地方註冊你的類。這基本上是type classes在起作用,令人驚訝的是,你真的不需要知道背後這個原理,直接簡單使用它們。另一個有趣的事情是,Json.writes輔助方法是基於宏的,而不是基於反射的。再次,Java開發人員不能使用這個庫,因為Java不支援型別類和宏。
結論
Scala開發人員往往不需要使用Spring進行依賴注入、不需要使用Hibernate訪問資料庫以及不需要使用基於反射的庫用於JSON序列化。這些目標實現方式是基於Java中不存在的具有特定Scala特性的解決方案。因此,Scala不是一個更好的Java,而是一個具有自己的生態系統,最佳實踐和方法的非常獨特的語言。如果你遇到一個仍然相信“Scala是更好的Java”神話的人,請傳送他們這篇文章。
相關文章
- 這樣的結構不是更好麼?
- 併發不是並行 它更好!並行
- Scala與Java的關係Java
- Scala呼叫Java類Java
- Java不是新的CobolJava
- 我們需要更多的程式設計師,而不是更好的工具程式設計師
- 從 Java 到 Scala(二):objectJavaObject
- 向Java開發者介紹ScalaJava
- Akka系列(五):Java和Scala中的FutureJava
- 從 Java 到 Scala (三): object 的應用JavaObject
- Akka 系列(五):Java 和 Scala 中的 FutureJava
- 如何寫出更好的Java程式碼Java
- Java不是增強的HTML(轉)JavaHTML
- 從 Java 到 Scala(四):TraitsJavaAI
- 快速排序(oc/java/python/scala)排序JavaPython
- Java 8會打敗Scala嗎?Java
- Scala—Java的避難所之main(String[])JavaAI
- 學Java還是前端更好?Java前端
- Java16的Vector API更好支援機器學習JavaAPI機器學習
- 【Scala篇】--Scala中的函式函式
- Java中AsynchronousFileChannel不是真正的非同步Java非同步
- 不是Java高手別看Java
- JWT 還是 session 根據實際業務使用不是更好嗎JWTSession
- Spark SQL scala和java版本的UDF函式使用SparkSQLJava函式
- 面向 Java 開發人員的 Scala 指南: 類操作Java
- Scala學習(五)---Scala中的類
- 選擇排序(OC/java/python/scala)排序JavaPython
- Java,Pyhon,Scala比較(一)map,reduceJava
- Java,Python,Scala比較(三)wordcountJavaPython
- Java之外選擇Scala還是Groovy?Java
- 更好的 java 重試框架 sisyphus 背後的故事Java框架
- Java和Python哪個更好?JavaPython
- 【Scala】Scala之ObjectObject
- 看看你是不是Java牛人Java
- 用Java編寫更好的不可變DTO的技巧 - SebJava
- 更好的 java 重試框架 sisyphus 的 3 種使用方式Java框架
- 有趣的 Scala 語言: 簡潔的 Scala 語法
- scala和java資料型別轉換Java資料型別