Share E-Book

Effective Kotlin Best practices, 2nd Edition (Marcin Moskala)(Z-Library)

Author

Rating No ratings yet

Log in to rate

Java
Language English

This book is a guide for Kotlin developers on how to become an excellent Kotlin developer. Kotlin is a powerful and pragmatic language, but it's not enough to know about its features. You also need to know when they should be used and in what way. This book presents and explains in-depth the best practices for Kotlin development. Each item is presented as a clear rule of thumb, supported by detailed explanations and practical examples. It's a comprehensive guide of best practices for Kotlin code quality: safety, readability, code design and efficiency. What you will learn You will learn how to make better Kotlin development in terms of safety, readability, maintainability and performance. The book also covers some advanced topics like inline functions and classes, DSLs or platform types. Who this book is for This book was written for Kotlin developers who want to learn and understand how to write high-quality code. It assumes some experience with Kotlin or at least with Swift, Java or Scala. It is directed towards all kinds of Kotlin developers and isn't specific to mobile or backend development. The purpose of this book The purpose of Effective Kotlin is to teach and promote the best practices for Kotlin developers, as well as the way Kotlin features can and should be used to improve code. Reader Testimonials Rafal Kuźmiński: Well done! I've read a few items and I have to admit that I learned some interesting stuff. Great book: ) Hanno Günther: Really love this book!

Format PDF
Size 1.9 MB
8
Views
(First 20 pages)

Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

Page 1
(This page has no text content)
Page 2
Effective Kotlin Best practices MarcinMoskała This book is available at http://leanpub.com/effectivekotlin This versionwas published on 2024-10-10 This is a Leanpub book. Leanpub empowers authors and publisherswith the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools andmany iterations to get reader feedback, pivot until you have the right book and build traction once you do. © 2018 - 2024MarcinMoskała
Page 3
Tweet This Book! Please helpMarcinMoskała by spreading theword about this book onTwitter! The suggested tweet for this book is: I just bought@EffectiveKotlin! The suggested hashtag for this book is #effectivekotlin. Find outwhat other people are saying about the book by clicking on this link to search for this hashtag onTwitter: #effectivekotlin
Page 4
Formy parents
Page 5
Contents Introduction: Be pragmatic 1 Who is this book for? 4 Code Sources 7 Part 1: Good code 11 Chapter 1: Safety 12 Item 1: Limitmutability 13 Item 2: Eliminate critical sections 25 Item 3: Eliminate platform types as soon as possible 34 Item4:Minimize the scope of variables 40 Item 5: Specify your expectations for arguments and state 46 Item 6: Prefer standard errors to customones 56 Item 7: Prefer a nullable or Result result typewhen the lack of a result is possible 58 Item 8: Close resourceswith use 63 Item 9:Write unit tests 66 Chapter 2: Readability 69 Item 10: Design for readability 70 Item11:Anoperator’smeaningshouldbeconsistentwith its functionname 75 Item 12: Use operators to increase readability 80 Item 13: Considermaking types explicit 84 Item 14: Consider referencing receivers explicitly 87 Item 15: Properties should represent a state, not a behavior 93 Item 16: Avoid returning or operating on Unit? 97 Item 17: Consider naming arguments 99 Item 18: Respect coding conventions 104 Part 2: Codedesign 107 Chapter 3: Reusability 108 Item 19: Do not repeat knowledge 109 Item 20: Do not repeat common algorithms 116
Page 6
CONTENTS Item 21: Use generics when implementing common algorithms 120 Item 22: Avoid shadowing type parameters 123 Item 23: Consider using variancemodifiers for generic types 125 Item 24: Reuse between different platforms by extracting commonmod- ules 127 Chapter 4: Abstractiondesign 132 Item 25: Each function should be written in terms of a single level of abstraction 136 Item 26: Use abstraction to protect code against changes 142 Item 27: Specify API stability 155 Item 28: Considerwrapping external APIs 158 Item 29:Minimize elements’ visibility 160 Item 30: Define contracts with documentation 164 Item 31: Respect abstraction contracts 174 Chapter 5: Object creation 176 Item 32: Consider factory functions instead of constructors 177 Item 33: Consider a primary constructorwith named optional arguments 192 Item 34: Consider defining a DSL for complex object creation 202 Item 35: Consider using dependency injection 213 Chapter 6: Class design 216 Item 36: Prefer composition over inheritance 217 Item 37: Use the datamodifier to represent a bundle of data 228 Item 38: Use function types or functional interfaces to pass operations and actions 235 Item 39: Use sealed classes and interfaces to express restricted hierarchies 241 Item40: Prefer class hierarchies instead of tagged classes 244 Item41: Use enum to represent a list of values 249 Item42: Respect the contract of equals 256 Item43: Respect the contract of hashCode 268 Item44: Respect the contract of compareTo 276 Item 45: Consider extracting non-essential parts of your API into exten- sions 279 Item46: Avoidmember extensions 284 Part 3: Efficiency 289 Chapter 7:Make it cheap 290 Item47: Avoid unnecessary object creation 291 Item48: Consider using object declarations 296 Item49: Use cachingwhen possible 298 Item 50: Extract objects that can be reused 301
Page 7
CONTENTS Item 51: Use the inline modifier for functions with parameters of func- tional types 304 Item 52: Consider using inline value classes 318 Item 53: Eliminate obsolete object references 326 Chapter 8: Efficient collectionprocessing 333 Item54:PreferSequences forbig collectionswithmore thanoneprocess- ing step 337 Item 55: Consider associating elements to amap 350 Item 56: Consider using groupingBy instead of groupBy 355 Item 57: Limit the number of operations 359 Item 58: Consider Arrays with primitives for performance-critical pro- cessing 362 Item 59: Consider usingmutable collections 365 Item 60: Use appropriate collection types 367 Dictionary 374
Page 8
Introduction: Be pragmatic Stories of the origins of popular programming languages are often fascinating. The prototype of JavaScript (namedMocha back then)was created in just 10 days. Its creators first consideredusingJavabutwanted tomakea simpler language for Web designers¹. Scala was created at a university by a scientist, Martin Odersky. He wanted to transfer some concepts from functional programming into the Java object- oriented programmingworld. It turned out that theseworlds are connectable². Java was originally designed in the early ‘90s for interactive television and set- top boxes by a team working at Sun called “The Green Team”. Eventually, this languagewas too advanced for the digital cable television industry at the time. It ended up revolutionizing general programming instead³. Many languageswere designed for a totally different purpose thanwhat they are used for today.Manyoriginated as experiments, as can still be seen in them today. The differences in the Kotlin story are that: 1. Since the beginning, it has been created and designed to be a general- purpose programming language that is suitable for large applications. 2. The creators of Kotlin are taking their time. The development of Kotlin started in 2010, and the first officially stable version was released in Febru- ary of 2016. During this period, a lot changed. If you find some code from the first proposals, it looks almost nothing like Kotlin today. Kotlin was created as a pragmatic language for practical applications, and this is reflected in its design. For instance, as opposed to academic or hobbyist languages, it has never had ambitions to experiment with new concepts. Kotlin has introduceda fewnewconcepts (likepropertydelegation), but theKotlin team is very conscientious and prefers to analyze how existing concepts have coop- erated and worked for other languages⁴. They are always trying to understand the strengths and weaknesses of other languages and build on them. This is a good strategy for JetBrains (the creators of Kotlin) since it is also the creator of IntelliJ, an Integrated Development Environment (IDE). They have a lot of data ¹Read about it here: kt.academy/l/wiki-js and kt.academy/l/js-origins ²Read about it here: kt.academy/l/scala-origins ³Read about it here: kt.academy/l/java-origins ⁴I amtalkingabout language itself. Some librariesprovidedbyKotlin teamare full of experimental ideas. Kotlin Coroutines library is a good example. 1
Page 9
Introduction: Be pragmatic 2 and knowledge about how various languages are used, and they have specialists who understand each of these languages. For that same reason, Kotlin is also different because it has reached a new level of cooperation between the IDE and the language. Code analysis in IntelliJ or Eclipse is done using the same compiler that is used to compile the code. Thanks to that, Kotlin can freely introduce more advanced smart casting and type inference without requiring IDE changes. The Kotlin team also supports developersbyconstantly improvingIntelliJwarnings,hints, and lints.Becauseof thismechanism,most of the classic optimization hints don’t need to be collected in books or articles because they can just be provided via discrete warnings exactlywhere they are needed. The philosophy of Kotlin Every language has its own philosophy that determines design decisions. The central point of Kotlin’s philosophy is pragmatism. This means that, in the end, all choices need to serve business needs, like: • Productivity - application production is fast. • Scalability - asanapplicationgrows, itsdevelopmentdoesnotbecomemore expensive. Itmay even get cheaper. • Maintainability -maintenance is easy. • Reliability - applications behave as expected, and there are fewer errors. • Efficiency - applications run fast and need fewer resources (memory, pro- cessor, etc.). As aprogrammingcommunity,wehave tried to satisfy theseneeds forquite some time.Basedonourexperiences,wehavedevelopeddifferent toolsandtechniques. For instance,wehave learned that automatic testing is very important to prevent errors that are accidentally added toone featurewhensomeonemodifies another. There are also rules to follow.For instance, the SingleResponsibility Principle from SOLID⁵ helps us with the same problem. Throughout this book, we will mention many such rules. The programming community also found that some less-abstract values (from theprogrammers’ point of view) support higher-level businessneeds.TheKotlin team collected values that are important in terms of language design and used them as a point of reference for all design decisions. These values are: • Safety ⁵SOLID is a popular set of principles for OOP, introduced and popularized by Robert C.Martin.
Page 10
Introduction: Be pragmatic 3 • Readability • Powerful code reusability • Tool friendliness • Interoperabilitywith other languages I would add another point that is normally not included, but that can be seen in many decisions: • Efficiency These requirements were not only present at the inception of Kotlin: they are still with us today, and each change is considered with them in mind. I will also show that they are all very strongly reflected inKotlin’s design.Thiswas possible thanks to the fact that Kotlin was intentionally kept in beta for nearly 6 years. During this time, it was changing at all levels. It takes a lot of time to shape the design of a programming language to reflect high-level values. The Kotlin creators did a good job of that. The purpose of this book To really unleash the advantages of Kotlin, we need to use it properly. Knowing the features and the standard library (stdlib) is not enough. Themain goal of this book is to explain how to use different Kotlin features to achieve safe, readable, scalable, and efficient code. Since this book iswritten tohelp developers improve their code, it also touches onmany general rules for programmers. You can find the influence of programming classics like Clean Code, Effective Java, Structure and Implementation of Computer Programs, Code Complete, and many more. You can also feel the influence of suggestions from influential presentations and Kotlin forums.This book tries to offer asmuchknowledge about best practices in Kotlin as possible, nomatter fromwhere it originated. You can call it a collection of best practices, but it differs from classic “Effective X” books because of Kotlin’s characteristics. The Effective Java book contains many warnings about internal Java problems. In Kotlin, such problems are mostly eliminated by the Kotlin team. In contrast to Java, Kotlin is not worried about deprecating something and fixing it in the future⁶. In the worst case, the Kotlin team controls a powerful IDE that can do nearly anymigration to a better alternative.Most“EffectiveX”booksalsohintatpreferringtousesomefunctions or constructs over others. These kinds of suggestions are rarely useful in Kotlin as most of them already have a warning or hint in IntelliJ. I have left only a few such items in this book. This book is different: it concentrates on higher- level goodpractices that come fromauthorities, theKotlin creators, and frommy experience as a developer, consultant, and trainer for international companies worldwide. ⁶KotlinConf 2018 keynote by Andrey Breslav.
Page 11
Introduction: Be pragmatic 4 Who is this book for? This book does not teach the basics. It assumes that you have enough knowledge andskills todoKotlindevelopment. Ifyoudon’t, I recommendstartingwithsome resources designed for beginners, like my books Kotlin Essentials and Functional Kotlin. Effective Kotlin is for experienced Kotlin developers. I will assume that even experienced developers might not know some features. This is why I explain concepts such as: • Properties • Platform types • Named arguments • DSL creation • Inline classes and functions I want this book to be a complete guide for Kotlin developers on how to become amazing Kotlin developers. Book design Concepts in the book are grouped into three parts: • Good code - more general rules about writing good-quality code. This part is for every Kotlin developer, no matter how big their project is. It starts from items about safety and later talks about readability. It is not a coinci- dence that the first chapter is dedicated to safety. I believe that program correctness is generally of the highest priority. Another chapter concerns readabilitybecausecode isnotonlyforacompilerbutalso forprogrammers. Evenwhenwework alone, wewant readable and self-explanatory code. • Code design - this section is for developers creating projects or libraries in cooperation with other developers. This part is about conventions and declaring contracts. The Code design chapter will, in the end, reflect on readability and safety in terms of code design. This part is a bit more abstract at the beginning, but this lets it explore topics that are often omitted in books about code quality. This section is also about preparing our code for growth. Many items are about being ready for changes in the future and are therefore especially important for developers creating large projects. • Efficiency - this section is for developers who care about code efficiency. Most of the rules presented here do not come at the cost of development time or readability, so they are suitable for everyone. However, they are particularly important for developers implementing high-performance ap- plications, libraries, or applications formillions of users.
Page 12
Introduction: Be pragmatic 5 Each part is divided into chapters, which are subdivided into items. Here are the chapters in each part: Part 1: Good code • Chapter 1: Safety • Chapter 2: Readability Part 2: Code design • Chapter 3: Reusability • Chapter 4: Abstraction design • Chapter 5: Objects creation • Chapter 6: Class design Part 3: Efficiency • Chapter 7:Make it cheap • Chapter 8: Efficient collection processing Each chapter contains items that are suggestions. The concept is that items are rules that, inmost cases, need an explanation, but once the idea is clear, it can be triggered just by this title. In the end, suggestions designed this way, with their explanations, shouldclearly showreadershowtowritegoodand idiomaticKotlin code. Chapter organization Chapters often start with themost important concept that is used in other items. A very visible example is Chapter 2: Readability, which starts with Item 10: Design for readability, but this is also true for: • Chapter 7: Make it cheap’s first item is Item 47: Avoid unnecessary object creation • Chapter 3: Reusability’s first item is Item 19: Do not repeat knowledge • Chapter 1: Safety’s first item is Item 1: Limitmutability Chapters can also end with an item that is generally less connected with the rest but presents an important concept that needs to be included, for instance: • Chapter 1: Safety’s last item is Item 9:Write unit tests • Chapter 2: Readability’s last item is Item 18: Respect coding conventions • Chapter 3:Reusability’s last item is Item24:Reuse betweendifferent platforms by extracting commonmodules
Page 13
Introduction: Be pragmatic 6 How should this book be read? Howshould thisbookberead?Thewayyou like it.Don’tbother jumpingbetween chapters. To some degree, one builds on another, but knowledge is presented so that the chapters should be understandable independently of the others. Having said that, you should read each chapter from the beginning as each is designed to form a flow. Choosewhatever chapter youwant to startwith, andyou can return to theothers later. If you feel bored with an item or chapter, skip it. This book was written withpleasure and shouldbe read the sameway. Labels It is impossible to write a book for everyone. This book is written primarily for experienced Kotlin developers who are already familiar with general best pro- gramming practices and looking for Kotlin-specific suggestions. Nevertheless, there are some items Idecided to includeeven though theyarenotKotlin-specific or theymight seembasic forexperienceddevelopers.Tomake it clearwhichthese are, I added the following labels at the beginning of such items: • Not Kotlin-specific - this item does not have Kotlin-specific suggestions, and similar arguments might be applied to other OOP languages like Java, C#, or Swift. If you are looking for Kotlin-specific content, skip such items. • Basics - thepresented suggestionsmight soundbasic for experiencedKotlin developers as they are already covered in other best-practices books, and they seem to be understood by the community. If a title seems clear to you, skip this item.
Page 14
Introduction: Be pragmatic 7 Code Sources The source code of all the snippets is published in the following repository: https://github.com/MarcinMoskala/effectivekotlin_sources Suggestions If you have any suggestions or corrections regarding this book, send them to contact@kt.academy
Page 15
Introduction: Be pragmatic 8 Acknowledgments This book would not be so good without the great reviewers who greatly influ- enced it with their suggestions and comments. I would like to thank all of them. Here is the list of reviewers, starting from themost active ones. MártonBraun - AKotlin enthusiast since the version 1.0 of the language.He is currentlyworking atGoogle,mak- ing Kotlin great to use for Android development. Uni- versity lecturer, StackOverflow contributor, and open source library author on the side. Márton’s useful comments, suggestions, and correc- tions strongly influenced chapters 1 to 6. He suggested changes in the names of chapters, supported the reorga- nization of the book, and contributedmany important ideas. David Blanc - After graduating in Computer Science fromINSA(aFrenchEngineeringschool),Davidworked as a Java engineer for 8 years at various French IT com- panies; in 2012, hemoved tomobile application develop- ment on iOS and Android. In 2015, he decided to focus on Android and joined i-BP (an IT department of the banking group BPCE) as an Android expert. He is now passionate about Android, clean code, and, of course, Kotlin programming since version 1.0. David gave many on-point corrections and corrected the wording for nearly all chapters. He suggested some good examples and useful ideas. JordanHansen - Jordan has been developing on and off since he was 10. He started developing full-time when he graduated from the University of Utah. He started evaluating Kotlin version 0.6 as a viable language and has been using it as his primary language since version 0.8. He was part of an influential team that brought Kotlin to his entire organization. Jordan loves playing tabletop gameswith his family. Jordan strongly influencedmost of the book and providedmany corrections and suggestions for snippets and titles.He suggested a deeper explanation ofDSL and howthe itemdedicated tounit testing couldbe shortened.Heencouragedcorrect technical wording.
Page 16
Introduction: Be pragmatic 9 Juan Ignacio Vimberg - The most active reviewer in the toughest part of this book: Part 3: Efficiency. Also strongly influenced chapters 1 to 4. He suggested showing correct benchmarks and describing Semantic Versioning. Kirill Bubochkin - Gave perfectly on-point and well-thought-out comments throughout the book. FabioCollini - Great review, especially for Chapters 4 and 5. Bill Best - An important reviewer who influenced chapters 6 to 8, where he left important corrections. Geoff Falk - Helped improve the language, grammar, and some code snippets, especially in chapters 2 and 5. DaniloHerrera - Influenced chapter 3 and greatly influencedChapter 4: Abstrac- tion design. AllanCaine - Strongly influenced Chapter 5: Object creation. EdwardSmith - Strongly influenced Chapter 6: Class design. JuanManuel Rivero - Reviewed Chapters 6, 7, and 8.
Page 17
Introduction: Be pragmatic 10 I would also like to thank: • Nicola Corti, for great suggestions andwording improvements. • Marta Raźniewska, whomade the drawings at the start of each section. • Most active alpha testers: Pablo Guardiola, Hubert Kosacki, Carmelo Iriti andMaria Antonietta Osso. • Everyone who helped this book by sharing news about it or sharing feed- back and feelingswithme.
Page 18
Part 1: Good code 11
Page 19
Chapter 1: Safety Whydowedecide touseKotlin inourprojects insteadofJava,JavaScript, orC++? For developers, the answer is often that Kotlin is amodern languagewith a lot of useful features. For business, the answer is usually that Kotlin is a safe language, meaning that it is less prone to errors due to its design.Youdon’tneed tohave any experience with development to get upset when an application crashes or there is an error on awebsite that does not let you check out after you’ve spent an hour addingproducts toyourbasket. Fewercrashes improve the livesofbothusers and developers, thus providing significant business value. Safety is important for us, and Kotlin is a really safe language, but it still needs developer support to be truly safe. In this chapter, we’ll talk about the most im- portant best practices for safety in Kotlin.We’ll see howKotlin features promote safety and how we can use them properly. The general purpose of every item in this chapter is to produce code that is less prone to errors. 12
Page 20
Chapter 1: Safety 13 Item 1: Limit mutability In Kotlin, we design programs in modules, each of which comprises different kinds of elements, such as classes, objects, functions, type aliases, and top-level properties. Someof theseelements canholda state, for instance,byhavingaread- write var property or by composing amutable object: var a = 10 val list: MutableList<Int> = mutableListOf() When an element holds a state, the way it behaves depends not only on how you use it but also on its history. A typical example of a class with a state is a bank account (class) that has somemoney balance (state): class BankAccount { var balance = 0.0 private set fun deposit(depositAmount: Double) { balance += depositAmount } @Throws(InsufficientFunds::class) fun withdraw(withdrawAmount: Double) { if (balance < withdrawAmount) { throw InsufficientFunds() } balance -= withdrawAmount } } class InsufficientFunds : Exception() val account = BankAccount() println(account.balance) // 0.0 account.deposit(100.0) println(account.balance) // 100.0 account.withdraw(50.0) println(account.balance) // 50.0 Here BankAccount has a state that represents howmuchmoney is in this account. Keepinga state is adouble-edged sword.On theonehand, it is veryuseful because
The above is a preview of the first 20 pages. Register to read the complete e-book.

Recommended for You

Loading recommended books...
Failed to load, please try again later

Tip the Site

Scan the WeChat Pay or Alipay code to tip. No login required.

WeChat Pay
Alipay
← Back to List