- Java到Kotlin:代碼重構指南
- (英)鄧肯·麥格雷戈 (英)納特·普萊斯
- 4864字
- 2025-01-03 16:16:32
前言
你好,我們是Duncan和Nat。當你閱讀這篇前言的時候,你可能正在考慮是否要花費幾小時來閱讀本書的剩余部分。那就讓我們開門見山:
本書不會教你如何使用Kotlin編寫代碼。
我們原本打算寫一本這樣的書,但很快就想到Kotlin是一門大型語言,撰寫一本這樣的書的時間會比我們想象中要長。此外,這個領域已經有一些很棒的書籍,我們不想與它們競爭。
因此我們決定讓事情更簡單,只聚焦于教授Java開發人員如何使用Kotlin,并通過一個名為“重構為Kotlin”的工作坊來進行教學。也就是說,通過轉化現有Java代碼來教授Kotlin語言,是為了那些希望利用現有知識快速普及Kotlin的Java團隊量身定制的。然后我們著手寫這樣一本書,但很快又想到Kotlin仍然是一門大型語言,我們仍需要很長的時間來撰寫。我們還發現,有積極性和資深的Java開發人員可以很快掌握Kotlin的大部分知識。在語言特征上進行深耕可能會獲得目標讀者的贊賞,但這樣顯得有點自詡清高。于是我們放棄了這個想法,所以:
本書不會教你Kotlin語言。
那么,為什么你要讀這本書呢?因為我們寫了一本在我們初次接觸Kotlin時希望擁有的書。我們都是資深的程序員,熟知Java以及Java生態。我們希望你也是。和我們一樣,你可能在其他幾種語言上也有經驗。你已經掌握了Kotlin的基本知識,知道要充分利用這門語言,需要用不同的方式設計你的系統。你發現在Kotlin中,有些事情比Java簡單得多,有些功能(如受檢異常)根本就不存在。你不想僅僅是采用Kotlin的語法來編寫Java代碼。
你可能身處技術領導職位,或者已經成功說服了團隊采用Kotlin。為了讓項目采用Kotlin,你可能花費了一些成本。現在你需要確保轉型順利進行。
你可能負責一個Java代碼庫,希望確保引入Kotlin不會破壞現有的關鍵業務代碼?;蛘吣憧赡軓牧汩_始一個Kotlin項目,但意識到你的設計靈感更傾向于Java和對象,而不是Kotlin和函數。
如果你身處這樣的境地,那么你找對了地方。這本書將幫助你調整思維和設計,以充分利用Kotlin。然而這還不夠,因為你需要維護和改進現有的代碼。所以我們還展示了如何使用IntelliJ IDE中內置的自動重構工具逐步且安全地從Java語法遷移到Kotlin語法,并從Java思維轉變到Kotlin思維。
本書的組織方式
本書講的是如何從Java過渡到Kotlin,主要關注代碼,但也涉及項目和組織。每章都講述了從Java過渡到Kotlin的某個方面,以及典型Java項目在這個過程中可以改進的某個方面。多數章節都是以“從Java方式到Kotlin方式”這種模式命名的,我們建議你選擇后者而不是前者。這可能是因為Kotlin使Java中很難實現的方法變得更容易,或者是因為Kotlin規避了Java中常見的方法,以引導設計向更少的錯誤、更簡潔和工具更友好的方向前進。
我們不僅僅建議你采用Kotlin方式,相關章節還展示了如何進行轉換。我們不僅僅是重寫Java,還通過安全的方式逐步重構為Kotlin方式,并允許維護混合語言代碼庫。
我們是如何挑選主題的
我們首先分析了Java和Kotlin開發人員對各自語言的使用情況,并進行了采訪,以確定兩種語言的差異和混淆之處。這是通過對33459個開源的Java和Kotlin代碼庫進行機器學習分析得到的結果。這些分析幫助確定了候選主題,我們用“從什么到什么”的形式標記候選主題,然后根據頻率和開發人員痛點系數對其進行排序,以確定應該選擇哪些主題。最后,我們根據“……”對剩下的主題進行排序。在這里用“……”不太好,但我們不能對你撒謊。事實上,我們從一開始就選擇了想寫的主題,我們認為這些主題會有趣且有益。第9章、第15章、第20章都是典型的例子。我們還尋找了Kotlin和Java差異顯著的地方,通過思考它們之間為何不同,我們發現這是我們學到東西最多的地方。這導致了第4章、第6章、第8章等章節的產生。
在撰寫這些章節時,其他主題也自然而然地出現在候選名單上。特別是,在我們為某一章編寫重構步驟時,我們經常發現自己對代碼進行了一些改動,我們認為這些改動值得單獨成章。第10章、第11章、第13章就是這方面的例子。
這個過程產生的結果絕不是詳盡無遺的。如果你已經翻閱過目錄,你會發現有一些重要的主題并沒有提及。以協程(協同程序)為例:這里是本書唯一提及這個龐大主題的地方,因為我們發現協程并沒有改變我們編寫服務器端代碼的方式,所以我們不想寫關于它的任何內容。如果有空間和時間的話,我們還希望涉及以下主題:構建器、領域特定語言、反射、依賴注入框架、事務……
我們希望我們所寫的主題是你感興趣的。這本書主要是關于戰術而不是戰略的,關注的是我們可以贏得的“小戰斗”,而不是整個部門可以達成的大目標。隨著更大的主題浮現出來,我們會試著將它們串聯起來,并在最后一章(第23章)把事情歸結在一起,談論我們在寫作過程中學到的東西。
復雜度
如何評估軟件的內部質量?假設我們的軟件能夠滿足客戶的需求,如何比較兩種潛在的實現方案,或者評判一項變更是使軟件更好還是更差?我們的答案是復雜度。在其他條件相同的情況下,我們偏愛簡單的設計,這種設計可以產生可預測的行為。
當然,在某種程度上,簡單和復雜是因人而異的。我們有略微不同的個人喜好,所以有時會在某個實現方案是更好還是更差的問題上存在分歧。在這種情況下,我們會在相關章節中探討替代方案。然而,我們都相信函數式編程可以降低系統的復雜度,特別是與面向對象(O O)的消息傳遞結合使用時。
多年來,Java一直在朝著這個方向發展。Scala則朝著函數式編程的方向發展,但遠離了OO。我們發現Kotlin的編程方式可以讓我們以一種混合函數式編程和面向對象編程的方式來降低復雜度,讓普通開發人員發揮出最佳水平。
完美代碼
以大眾的視角,我們應該關注代碼質量。我們很想追求代碼的完美,因為我們知道你可能會根據代碼來評價我們,像眾多開發人員一樣,我們的自尊心與我們的產出質量息息相關。
但是,我們是工程師而不是藝術家。我們的工作是為客戶平衡范圍、進度和成本,除非代碼的質量影響到這三個更高的價值,否則沒有人真正關心它。
因此在示例中,我們盡量展示真實的生產代碼。起點的代碼有時不太好,因為畢竟我們還想展示如何改進它們。通常重構會先讓事情變得更糟,然后才會變得更好,所以絕不要根據各章中間的代碼來評價我們。在一章結束時,我們的目標是擁有足夠好的代碼,但不是完美到讓我們被指責浪費了客戶的錢。
話雖如此,我們有一個策略,即在完成了既定的主題后,應用一些有成效的變更來整理代碼,有時候甚至會拓展出一個新的主題,并撰寫一章來使代碼達到我們滿意的狀態。最終,我們既是工程師又是藝術家。
代碼格式
我們的代碼盡可能地遵循Java和Kotlin的標準編碼規范。
書中示例代碼的實際行長度比我們在IDE中通常設置的120個字符要短得多,因此,我們需要更頻繁地拆分代碼行,使其適應頁面寬度。我們的生產代碼可能在一行上有四五個變量或參數,但在本書中,我們通常只有一個參數。通過格式化示例代碼來適應版面,我們漸漸喜歡上了這種更加縱向的樣式。我們發現,Kotlin自然地傾向于占用更多的垂直空間,即便是Java,也可以通過縮短行、增加換行和更多的可視化對齊來提高代碼的可讀性。像書籍一樣,在IDE中進行水平滾動也不方便,我們在結對環節通過減少滾動和增加并排窗口來加以改進。每個參數單獨一行也能大大提高代碼版本之間的差異對比效率。我們希望它讀起來至少不會讓你感到痛苦,如果你不這么覺得,那么可以嘗試在自己的代碼中應用這種風格。
有時我們會隱藏與討論無關的代碼。以3個點的省略號開頭的行表示出于清晰或簡潔的目的省略了一些代碼。例如:

排版約定
本書中使用以下排版約定:
斜體(Italic)
表示新的術語、URL、電子郵件地址、文件名和文件擴展名。
等寬字體(Constant width)
用于程序清單,以及段落中的程序元素,例如變量名、函數名、數據庫、數據類型、環境變量、語句以及關鍵字。
該圖示表示提示或建議。
該圖示表示一般性說明。
該圖示表示警告或注意。
示例代碼
本書中的大多數示例代碼(來自重構部分的示例代碼)可以在GitHub上在線訪問。代碼后面附有參考鏈接,例如:

如果你正在閱讀本書的電子版,參考鏈接應該是指向GitHub上該文件版本的超鏈接。如果在紙質書上點擊鏈接,則沒有反應。但如果你將示例編號(此例中為0.1)輸入本書網站(https://java-to-kotlin.dev/code.html)的表單中,將帶你轉到相同位置的鏈接。
在Git中,不同的示例代碼(有時跨越多個章節)會在不同的分支中演進。步驟會被標記,例如,這里table-reader.1是標記。GitHub鏈接指向具有該標記的代碼,因此你可以在該版本中查看所示文件(此處為src/test/java/travelator/tablereader/TableReader-AcceptanceTests.kt)以及示例的其他內容。你還可以選擇其他標記以查看不同的版本,選擇不同的分支以查看不同的示例。為了更快地導航,你可以克隆代碼存儲庫,在IntelliJ中打開它,并使用Git工具窗口切換分支和版本。
示例代碼并不是真實的!代碼庫可以構建并通過測試,但它是虛構的。
可以訪問https://java-to-kotlin.dev詢問技術問題。
這里的代碼是為了幫助你更好地理解本書的內容。通常,可以在程序或文檔中使用本書中的代碼,而不需要獲得許可,除非需要大段地復制代碼。例如,使用本書中所提供的幾個代碼片段來編寫一個程序不需要得到我們的許可,但銷售或發布本書的示例代碼則需要獲得許可。引用本書的示例代碼來回答問題也不需要許可,將本書中的很大一部分示例代碼放到自己的產品文檔中則需要獲得許可。
非常歡迎讀者使用本書中的代碼,希望(但不強制)注明出處。注明出處時包含書名、作者、出版社和ISBN,例如:
Java to Kotlin,作者Duncan McGregor和Nat Pryce,由O’ Reilly出版,書號978-1-492-08227-9
如果讀者覺得對示例代碼的使用超出了上面所給出的許可范圍,歡迎通過permissions@oreilly.com聯系我們。
O'Reilly在線學習平臺(O'Reilly Online Learning)
40多年來,O'Reilly Media致力于提供技術和商業培訓、知識和卓越見解,來幫助眾多公司取得成功。
我們擁有獨一無二的專家和革新者組成的龐大網絡,他們通過圖書、文章、會議和我們的在線學習平臺分享他們的知識和經驗。O Reilly的在線學習平臺允許你按需訪問現場培訓課程、深入的學習路徑、交互式編程環境,以及O Reilly和200多家其他出版商提供的大量文本和視頻資源。有關的更多信息,請訪問http://oreilly.com。
如何聯系我們
對于本書,如果有任何意見或疑問,請按照以下地址聯系本書出版商。
美國:

中國:
北京市西城區西直門南大街2號成銘大廈C座807室(100035)
奧萊利技術咨詢(北京)有限公司
要詢問技術問題或對本書提出建議,請發送電子郵件至bookquestions@oreilly.com。
本書配套網站https://oreil.ly/java-to-kotlin上列出了勘誤表、示例以及其他信息。
關于書籍、課程、會議和新聞的更多信息,請訪問我們的網站http://www.oreilly.com。
我們在Facebook上的地址:http://facebook.com/oreilly
我們在Twitter上的地址:http://twitter.com/oreillymedia
我們在YouTube上的地址:http://youtube.com/oreillymedia
致謝
感謝Hadi Hariri向O Reilly建議我們寫這本書,感謝Zan McQuade聽從他的建議。感謝我們的編輯Sarah Grey,以及Kerin Forsyth和Kate Galloway整理所有內容。
感謝許多朋友和同事,以及一些可愛的陌生人,他們審查了各種版本的草稿。感謝Yana Afanasyeva、Jack Bolles、David Denton、Bruce Eckel、Dmitry Kandalov、Kevin Peel、James Richardson、Ivan Sanchez、Jordan Stewart、Robert Stoll、Christoph Sturm、Lukasz Wycisk、Daniel Zappold,以及我們的技術審稿人Uberto Barbini、James Harmon、Mark Maynard和Augusto Rodriguez。我們非常感謝他們提供的所有建議和對我們的鼓勵。
極限編程革命性地改變了我們編寫軟件的方式,我們都應該感謝Ward Cunningham和Kent Beck。同時也要感謝Martin Fowler,如果沒有他,可能不會有這本書。在英國,自1999年以來,極限星期二俱樂部一直在極限編程想法上進行創新,并吸引了一批開發人員。我們很幸運地與這個小組中許多才華橫溢的成員一起工作和學習。如果你有問題,如果沒有其他人可以幫到你,如果你能找到他們,也許你可以與他們一起工作。
Duncan的致謝
我的妻子Jo McGregor不了解我的工作內容,也不會讀完這本書,但她可能會讀到這部分。因此,感謝她忍受我寫作而不是陪伴她,以及在我陪伴她時仍在談論寫作。沒有她的支持和鼓勵,我無法完成這本書。還要感謝我們的兩個兒子Callum和Alistair,他們讓我們非常自豪。
感謝我的母親Vickie Kennish對我的寫作表現出濃厚的興趣,她在我們散步時經常詢問進展情況。我已故的父親John肯定會裝作不在意,但會向他的朋友炫耀這本書。我們漂亮的貓Sweet Pea已經離開了,但它不會被遺忘,它在我寫作過程中一直陪伴著我,只是在書完成之前去世了。
Robin Helliwell的友誼和支持一直伴隨著我,還有我的姐姐Lucy Seal和許多其他家庭成員。在我的職業生涯中,除了那些提供反饋的人之外,還要感謝Alan Dyke、Richard Care和Gareth Sylvester-Bradley,他們都對我有很大的影響。
Nat的致謝
當我告訴我的妻子Lamaan我計劃寫這本書時,她的第一反應并不是驚恐。因此,我要非常感謝她的鼓勵和支持。
感謝我的妹妹Lois Pryce和妹夫Austin Vince,書中的示例代碼受到他們的摩托車旅行、書籍和電影的啟發。
還要感謝Oliver和Alex?,F在這本書已經完成,我又可以提供音樂和游戲編程咨詢服務了。
- Data Visualization with D3 4.x Cookbook(Second Edition)
- 大話PLC(輕松動漫版)
- Manga Studio Ex 5 Cookbook
- Eclipse Plug-in Development:Beginner's Guide(Second Edition)
- Nginx Essentials
- Symfony2 Essentials
- Mobile Device Exploitation Cookbook
- Processing創意編程指南
- Hadoop大數據分析技術
- Emotional Intelligence for IT Professionals
- 邊玩邊學Scratch3.0少兒趣味編程
- Unity Android Game Development by Example Beginner's Guide
- 分布式架構原理與實踐
- Learning Jakarta Struts 1.2: a concise and practical tutorial
- ASP.NET Core and Angular 2