1. 程式人生 > >Java 9 模組化開發:核心原則與實踐

Java 9 模組化開發:核心原則與實踐

內容簡介

Java 9 向 Java 平臺引入了模組系統,這是一個非常重要的飛躍,標誌著模組化 Java 軟體開發的新紀元。當需要建立靈活且易於維護的程式碼時,模組化是一個關鍵的架構設計原則。本書給出了 Java 模組系統的明確概述,並演示瞭如何通過建立模組化應用程式來幫助管理以及降低複雜性。

作者引導我們瞭解了模組系統中的相關概念以及工具,介紹了可以將現有程式碼遷移到模組中的模式並以模組的方式構建新的應用程式。

本書特色:

  • 瞭解 Java 平臺自身如何實現模組化;
  • 學習模組化如何影響應用程式的設計、編譯、打包以及開發;
  • 編寫自己的模組;
  • 使用模式改進任意程式碼庫的可維護性、靈活性以及重用性;
  • 學習如何使用服務來建立解耦模組;
  • 將現有程式碼遷移到模組,並學習如何使用並不是模組的現有庫;
  • 建立優化的自定義執行時映像,從而改變裝載模組化 Java 應用程式的方式。

作者簡介

桑德 · 馬克(Sander Mak),荷蘭 Luminis 公司的一名研究員,開發了許多主要用於 JVM 上的模組化以及可擴充套件軟體,但也會在需要的地方使用 TypeScript。他經常在各種會議上發言,並熱衷於通過部落格(http://branchandbound.net)和作為 Pluralsight 平臺的講師分享知識。

保羅 · 巴克(Paul Bakker) Netflix 公司的一名高階軟體工程師,在其 Edge Developer Experience 團隊主要從事工具的開發,以提高公司內部開發人員的工作效率。曾與他人合作編著了 Modular Cloud Apps with OSGi

(由O''Reilly 出版公司出版)一書。Paul 經常在與模組化、容器技術相關主題的會議上發言。

本書內容

譯者序

JDK 9是 Java 開發工具包的第9個主要版本,於2017年7月下旬釋出,它帶來了許多令人興奮的新功能。Java 9定義了一套全新的模組系統。當代碼庫越來越大,建立盤根錯節的“義大利麵條式程式碼”的概率呈指數級增長,這時候就得面對兩個基礎問題。首先,很難真正地對程式碼進行封裝,而系統對不同部分(也就是 JAR 檔案)之間的依賴關係並沒有明確的概念。每一個公共類都可以被類路徑之下任何其他公共類所訪問,這樣就會導致無意中使用了並不想被公開訪問的 API。其次,類路徑本身也存在問題:你怎麼知曉所有需要的 JAR 都已經有了,或者是不是會有重複的項呢?模組系統把這兩個問題都解決了。

模組化的 JAR 檔案都包含一個額外的模組描述符。在這個模組描述符中,對其他模組的依賴是通過 requires 來表示的。另外,exports 語句控制著哪些包是可以被其他模組訪問的。所有不被匯出的包預設都封裝在模組裡。

本書共分為三部分,第一部分包括6章。第1章主要介紹了什麼是模組化以及 Java 9模組的主要特點。第2章學習瞭如何定義模組,以及使用哪些概念管理模組之間的互動。第3章在第2章的基礎上通過構建自己的模組進一步學習相關模組概念。第4章討論了可以解耦模組的服務。第5章和第6章探討了模組化模式,以及如何以最大限度地提高可維護性和可擴充套件性的方式使用模組。

第二部分包括4章。第7章和第8章重點介紹瞭如何將現有的程式碼遷移到模組中。第9章通過遷移案例詳細討論瞭如何實現遷移。如果你是一名庫的建立者或者維護者,那麼第10章將對你有所幫助,其介紹瞭如何向庫新增模組支援。

第三部分也包括4章,主要介紹了一些模組化開發工具。第11章學習了主要的 IDE 以及構建工具。第12章介紹瞭如何對模組進行測試。第13章和第14章主要介紹了自定義執行時映像以及對模組化未來的展望。

本書圖文並茂、技術新、實用性強,以大量的例項對 Java 9模組系統做了詳細的解釋,是學習 Java 9的讀者不可缺少的實用參考書籍。本書可作為 Java 程式設計人員的參考手冊,適合計算機技術人員使用。此外,書中還提供了相關參考資料,如果在閱讀過程中遇到不明白的方法或屬性,可以參閱相關內容。

參與本書翻譯的人有王淨、田洪、範園芳、範楨、胡訓強、晏峰、餘佳雋、張潔、何遠燕、任方燕。最終由王淨負責統稿。在此,要感謝我們的家人,他們總是無怨無悔地支援我們的一切工作。

在翻譯過程中,我們儘量保持原書的特色,並對書中出現的術語和難詞難句進行了仔細推敲和研究。但畢竟有少量技術是譯者在自己的研究領域中不曾遇到過的,所以疏漏和爭議之處在所難免,望廣大讀者提出寶貴意見。

最後,希望廣大讀者能多花些時間細細品味這本凝聚作者和譯者大量心血的書籍,為將來的職業生涯奠定良好的基礎。

王淨

2018年3月於廣州

什麼是 Java 中的模組化?對於一些人來說,模組化是一個開發原則,即對介面進行程式設計並隱藏實現的細節,這就是所謂的封裝學派(school of encapsulation)。對於另外一些人來說,模組化是指依賴類載入器來提供動態執行環境,這就是所謂的隔離學派(school of isolation)。還有一些人認為模組化指的是工件、儲存庫以及相關工具,這就是所謂的配置學派(school of configuration)。雖然單獨來看,這些觀點都是正確的,但它們都太片面,感覺更像是一個不太清晰的“大故事”的幾個片段。如果開發人員知道其部分程式碼僅供內部使用,那麼他們為什麼不能像隱藏類或欄位一樣容易地隱藏包呢?如果程式碼只能在依賴項存在的情況下編譯和執行,那麼這些依賴項為什麼不能順暢地從編譯過程流向打包過程,再到安裝過程,最後到執行過程呢?如果工具只有在提供了原始自描述工件時才能起作用,那麼如何重用那些只是普通 JAR 檔案的舊版本庫呢?

Java 9將模組作為 Java 平臺的高階功能,從而很自然地引入了模組化概念。模組是一組用於重用的包,這個簡單的概念對程式碼開發、部署以及執行的方式產生了非常深刻的影響。一旦將包放置到模組中,Java 中用來促進和控制“重用”的長期存在的機制(介面、訪問控制、JAR 檔案、類載入器以及動態連結)就能更好地工作。

首先,模組以其他機制無法實現的方式闡明瞭程式的結構。許多開發人員會驚訝地發現他們的程式碼結構並沒有想象得那麼好。例如,由多個 JAR 檔案組成的程式碼庫可以實現不同 JAR 檔案中類之間的迴圈,但在不同模組中的類之間的迴圈卻是禁止的。實現程式碼庫模組化的動機之一是一旦實現了模組化,就可以避免出現因為迴圈依賴所產生的“泥球”(ball of mud)[1]。此外,使用模組進行開發還可以實現通過服務進行程式設計,從而減少耦合並進一步提高抽象性。

其次,模組產生了其他機制無法實現的程式碼責任感。從模組中匯出包的開發人員實際上對 API 的穩定性做出了承諾,甚至模組本身的名稱也是 API 的一部分。如果開發人員將太多的功能捆綁到單個模組中,那麼就會導致該模組牽扯到大量與任何單一任務無關的依賴項;任何重用該模組的人都會意識到其雜亂無序的性質,即使模組的內部是隱藏的。使用模組進行開發可以促使每個開發人員思考其程式碼的穩定性和內聚性。

大多數人對桌布戲法都非常熟悉,即將桌布從桌子上迅速拿走,同時不能打翻盤子和杯子。對於那些使用 Java 9的人來說,設計一個可以嵌入 Java 虛擬機器(Java 虛擬機器由自20世紀90年代以來所開發的數以百萬計的類所控制)的模組系統感覺就像是反向表演桌布戲法。事實證明,模組化 JDK 導致了戲法的失敗,因為一些知名的庫為了自身的發展而不願意將模組系統應用於 JDK 模組所帶來的封裝。Java 9設計中的這種矛盾很難在學術上得到解決。最終,來自社群的長期反饋促使模組系統為開發人員提供了各種各樣的“槓桿”和“調節盤”,使得模組化平臺程式碼可以享受真正強大的封裝,而模組化應用程式程式碼可以享受“足夠強大”的封裝。隨著時間的推移,我們認為在模組化 JDK 方面進行的大膽選擇將會使得程式碼更加可靠。

只有當一個模組系統適用於所有人時,該系統才是最好的。今天建立模組的開發人員越多,明天就會有更多的開發人員建立模組。但是那些尚未建立自己模組的開發人員又該怎麼辦呢?毫不誇張地說,Java 9會像關注模組內的程式碼一樣關注模組外的程式碼。程式碼庫的作者是唯一應該對程式碼庫進行模組化的開發人員,在完成模組化之前,模組系統必須為模組中的程式碼提供一種方法來“接觸”模組之外的程式碼,而這也導致了自動模組的設計,本書將會詳細介紹這部分內容。

Sander 和 Paul 都是 Java 方面的專家,同時也是 Java 9生態系統可信任的指導者。他們身處 Java 9開發的最前沿,是遷移流行開源庫的先驅。本書面向那些對 Java 中模組化的核心原則和最佳實踐感興趣的人的,包括希望建立可維護元件的應用程式開發人員,尋求關於遷移和反射建議的庫開發人員,以及希望利用模組系統高階功能的框架開發人員。我希望本書可以幫助你創建出程式結構經得起時間考驗的 Java 程式。

Alex Buckley

Oracle Java 平臺組

聖克拉拉,2017年7月


[1] 泥球是指一個隨意化的雜亂的結構化系統,只是程式碼的堆砌和拼湊,往往會導致很多錯誤或者缺陷。—譯者注

前言

Java 9向 Java 平臺引入了模組系統,這是一個重大的飛躍,標誌著 Java 平臺上模組化軟體開發的一個新時代的開始。看到這些變化讓人感到非常興奮,希望讀者看完本書後也會感到興奮。在深入瞭解模組系統之前需要做好充分利用該系統的準備。

本書讀者

本書為那些想要提高應用程式的設計和結構的 Java 開發者而編寫。Java 模組系統改進了設計和構建 Java 應用程式的方法。即使你不打算馬上使用模組,瞭解 JDK 模組化本身也是非常重要的一步。在熟悉了本書第一部分所介紹的模組之後,希望你也能真正理解後續關於遷移的相關章節。

將現有程式碼移至 Java 9和模組系統將成為一項越來越常見的任務。

本書絕不是對 Java 的一般性介紹。我們假設你擁有在一個團隊中編寫過較大 Java 應用程式的經驗,在較大的 Java 應用程式中模組變得越來越重要。作為一名經驗豐富的 Java 開發人員,應該認識到類路徑所帶來的問題,從而有助於理解模組系統及其功能。

除了模組系統之外,Java 9中還有許多其他變化。然而,本書主要關注模組系統及其相關功能。當然,在適當的情況下,在模組系統的上下文中也會討論其他 Java 9功能。

編寫本書的原因

很多讀者從 Java 早期開始就是 Java 使用者,當時 Applet 還非常流行。多年來,我們使用和喜歡過許多其他平臺和語言,但 Java 仍然是主要工具。在構建可維護的軟體方面,模組化是一個關鍵原則。多年來人們花費了大量精力來構建模組化軟體,並逐漸熱衷於開發模組化應用程式。曾經廣泛使用諸如 OSGi 之類的技術來實現模組化,但 Java 平臺本身並不支援這些技術。此外,還可通過 Java 之外的其他工具學習模組化,比如 JavaScript 的模組系統。當 Java 9推出了期待已久的模組系統時,我們認為並不能只是使用該功能,還應該幫助其剛入職的開發人員瞭解模組系統。

也許在過去10年的某個時候你曾經聽說過 Jigsaw 專案。經過多年的發展,Jigsaw 專案具備了 Java 模組系統許多功能的原型。Java 的模組系統發展斷斷續續。Java 7和 Java 8最初計劃包含 Jigsaw 專案的發展結果。

隨著 Java 9的出現,長期的模組化嘗試最終完成了正式模組系統的實現。多年來,各種模組系統原型的範圍和功能發生了許多變化。即使你一直在密切關注該過程,也很難弄清楚最終 Java 9模組系統真正包含什麼。本書將會給出模組系統的明確概述,更重要的是將介紹模組系統能夠為應用程式的設計和架構做些什麼。

本書內容

本書共分為三個部分:

1)Java 模組系統介紹。

2)遷移。

3)模組化開發工具。

第一部分主要介紹如何使用模組系統。首先從介紹模組化 JDK 本身開始,然後學習建立自己的模組,隨後討論可以解耦模組的服務,最後探討模組化模式以及如何以最大限度地提高可維護性和可擴充套件性的方式使用模組。

第二部分主要介紹遷移。有可能讀者現在所擁有的 Java 程式碼不是使用專為模組系統而設計的 Java 庫。該部分介紹如何將現有程式碼遷移到模組中,以及如何使用尚未模組化的現有庫。如果你是一名庫的編寫者或者維護者,那麼這部分中有一章專門介紹瞭如何向庫新增模組支援。

第三部分(也是最後一部分)主要介紹工具。該部分介紹了 IDE 的現狀以及構建工具。此外還會學習如何測試模組,因為模組給(單元)測試帶來了一些新的挑戰,也帶來了機會。最後學習連結(linking)——模組系統另一個引人注目的功能。

雖然建議從頭到尾按順序閱讀本書,但是請記住並不是所有的讀者都必須這樣閱讀。建議至少詳細閱讀前四章,從而具備基本知識,以便更好地閱讀本書的其他章節。如果時間有限並且有現有的程式碼需要遷移,那麼可以在閱讀完前四章後跳到本書的第二部分。一旦完成了遷移,就可以回到“更高階”的章節。

使用程式碼示例

本書包含了許多程式碼示例。所有程式碼示例都可以在 GitHub(https://github.com/java9-modularity/examples)上找到。在該儲存庫中,程式碼示例是按照章節組織的。在本書中,使用下面的方法引用具體的程式碼示例:chapter3/helloworld,其含義是可以在“https://github.com/java9-modularity/examples/chapter3/helloworld”中找到示例。

強烈建議在閱讀本書時使用相關的程式碼,因為在程式碼編輯器中可以更好地閱讀較長的程式碼段。此外還建議親自動手改寫程式碼,如重現書中所討論的錯誤。動手實踐勝過讀書。

排版約定

下面列出的是書中所使用的字型約定:

斜體(Italic)

表示新術語、URL、電子郵件地址、檔名以及副檔名。

等寬字型(Constant width)

用於程式清單,以及在段落中引用程式元素,如變數或函式名稱、資料庫、資料型別、環境變數、語句和關鍵字。

等寬粗體(Constant width bold)

顯示應由使用者逐字輸入的命令或其他文字。

等寬斜體(Constant width italic)

顯示應該由使用者提供的值或由上下文確定的值所替換的文字。

Safari 線上電子書

Safari(前身為 Safari Books Online)是一個基於會員制的為企業、政府、教育工作者和個人提供培訓和參考的平臺。

會員可以訪問來自250家出版商的書籍、培訓視訊、學習路徑、互動式教程和精心策劃的播放列表,包括 O'Reilly Media、Harvard Business Review、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Adobe、Focal Press、Cisco Press、John Wiley&Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、AdobePress、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones&Bartlett,以及Course Technology,等等。

更多資訊,請訪問 http://oreilly.com/safari

如何聯絡我們

對於本書,如果有任何意見或疑問,請按照以下地址聯絡本書出版商。

美國:

O'Reilly Media,Inc.

1005Gravenstein Highway North

Sebastopol,CA 95472

中國:

北京市西城區西直門南大街2號成銘大廈 C 座807室(100035)

奧萊利技術諮詢(北京)有限公司

要詢問技術問題或對本書提出建議,請傳送電子郵件至:

[email protected]

要獲得更多關於我們的書籍、會議、資源中心和 O’Reilly 網路的資訊,請參見我們的網站:

http://www.oreilly.com

http://www.oreilly.com.cn

我們在 Facebook 上的主頁:
http://facebook.com/oreilly

我們在 Twitter 上的主頁:
http://twitter.com/oreillymedia

我們在 YouTube 上的主頁:
http://www.youtube.com/oreillymedia

致謝

編寫本書的想法來源於2015年在 JavaOne 會議上與來自 O’Reilly 的 Brian Foster 的一次談話,非常感謝你委託我們參與這個專案。從那時起,很多人對本書的編寫提供了幫助。

感謝 Alex Buckley、Alan Bateman 和 Simon Maple 所給出的重要技術評論和對本書所提出的許多改進意見。此外,還要感謝 O’Reilly 的編輯團隊,Nan Barber 和 Heather Scherer 考慮到了所有的組織細節。

如果沒有妻子 Suzanne 的堅定支援,編寫本書是不可能的。多少個夜晚和週末,我都無法陪伴妻子和三個孩子。感謝你一直陪我到最後!此外,還要感謝 Luminis(http://luminis.eu/)為編寫本書所提供的支援。我很高興能成為公司的一員,我們的口號是“知識是共享的唯一財富”。

Sander Mak

我也要感謝妻子 Qiushi,在我編寫這第二本書籍時始終支援我,即使在我們搬到世界的另一個位置的時候。此外,還要感謝 Netflix(http://netflix.com/)和 Luminis(http://luminis.eu/),感謝它們給予我編寫本書的時間和機會。

Paul Bakker

本書第1章、第7章、第13章和第14章的漫畫由 Oliver Widder(http://geek-and-poke.com/)建立,並獲得 Creative Commons Attribution 3.0Unported(CC BY 3.0)(http://creativecommons.org/licenses/by/3.0/deed.en_US)的許可。本書的作者將漫畫改為橫向和灰色。

第1章 模組化概述
第2章 模組和模組化 JDK
第3章 使用模組
第4章 服務
第5章 模組化模式(一)
第5章 模組化模式(二)
第6章 高階模組化模式
第7章 沒有模組的遷移
第8章 遷移到模組
第9章 遷移案例研究:Spring 和 Hibernate
第10章 庫遷移
第11章 構建工具和 IDE
第12章 測試模組
第13章 使用自定義執行時映像進行縮減
第14章 模組化的未來

閱讀全文: http://gitbook.cn/gitchat/geekbook/5c189a881e59245d4d2aac4f