Statistics
5
Views
0
Downloads
0
Donations
Support
Share
Uploader

高宏飞

Shared on 2026-02-13

AuthorMarcin Moskala

Effective Kotlin summarizes the best practices and experiences of the Kotlin community, together with a deep explanation of some lesser-known Kotlin functionalities. All of the best practices are presented as simple rules with detailed explanations. Kotlin is a powerful and pragmatic language, but it's not enough to know about its features. We also need to know when they should be used and in what way. This book is a guide for Kotlin developers on how to become excellent Kotlin developers. It 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. The purpose of this book: To really unleash the advantages of Kotlin, we need to use it properly. Knowing features and the standard library (stdlib) is not enough. The main goal of this book is to explain how to use different Kotlin features to achieve safe, readable, scalable, and efficient code. Since this book is written to help developers get better at writing code, it also touches on many 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 find influence from presentations and Kotlin forums. This book tries to compose as much knowledge about best practices in Kotlin as possible, no matter where it originated. You can call it a collection of best practices; though it differs from classic “Effective X” books because of Kotlin 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 any migration to a better alternative. For whom is this book written? This book is not

Tags
No tags
Publisher: Leanpub
Publish Year: 2021
Language: 英文
Pages: 439
File Format: PDF
File Size: 9.7 MB
Support Statistics
¥.00 · 0times
Text Preview (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.

(This page has no text content)
Effective Kotlin Best practices Marcin Moskala This book is for sale at http://leanpub.com/effectivekotlin This version was published on 2021-02-18 This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process. Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and many iterations to get reader feedback, pivot until you have the right book and build traction once you do. © 2018 - 2021 Marcin Moskala
Tweet This Book! Please help Marcin Moskala by spreading the word about this book on Twitter! The suggested tweet for this book is: I just bought @EffectiveKotlin! The suggested hashtag for this book is #effectivekotlin. Find out what other people are saying about the book by clicking on this link to search for this hashtag on Twitter: #effectivekotlin
Contents Introduction: Be pragmatic 1 Part 1: Good code 13 Chapter 1: Safety 14 Item 1: Limit mutability 15 Item 2: Minimize the scope of variables 35 Item 3: Eliminate platform types as soon as possible 42 Item 4: Do not expose inferred types 50 Item 5: Specify your expectations on arguments and state 53 Item 6: Prefer standard errors to custom ones 64 Item 7: Prefer null or Failure result when the lack of result is possible 66 Item 8: Handle nulls properly 70 Item 9: Close resources with use 81 Item 10: Write unit tests 84 Chapter 2: Readability 88 Item 11: Design for readability 90 Item 12: Operator meaning should be consistent with its function name 97 Item 13: Avoid returning or operating on Unit? 102 Item 14: Specify the variable type when it is not clear 104 Item 15: Consider referencing receivers explicitly 106 Item 16: Properties should represent state, not behavior 114 Item 17: Consider naming arguments 120
CONTENTS Item 18: Respect coding conventions 127 Part 2: Code design 130 Chapter 3: Reusability 131 Item 19: Do not repeat knowledge 133 Item 20: Do not repeat common algorithms 142 Item 21: Use property delegation to extract common property patterns 147 Item 22: Use generics when implementing common algo- rithms 154 Item 23: Avoid shadowing type parameters 158 Item 24: Consider variance for generic types 160 Item 25: Reuse between different platforms by extracting common modules 173 Chapter 4: Abstraction design 178 Item 26: Each function should be written in terms of a single level of abstraction 183 Item 27: Use abstraction to protect code against changes 190 Item 28: Specify API stability 206 Item 29: Consider wrapping external API 210 Item 30: Minimize elements visibility 212 Item 31: Define contract with documentation 217 Item 32: Respect abstraction contracts 231 Chapter 5: Object creation 234 Item 33: Consider factory functions instead of constructors 235 Item 34: Consider a primary constructor with named optional arguments 251 Item 35: Consider defining a DSL for complex object creation 262 Chapter 6: Class design 274 Item 36: Prefer composition over inheritance 275
CONTENTS Item 37: Use the data modifier to represent a bundle of data 289 Item 38: Use function types instead of interfaces to pass operations and actions 297 Item 39: Prefer class hierarchies to tagged classes 302 Item 40: Respect the contract of equals 309 Item 41: Respect the contract of hashCode 323 Item 42: Respect the contract of compareTo 333 Item 43: Consider extracting non-essential parts of your API into extensions 337 Item 44: Avoid member extensions 342 Part 3: Efficiency 346 Chapter 7: Make it cheap 347 Item 45: Avoid unnecessary object creation 349 Item 46: Use inline modifier for functions with parame- ters of functional types 364 Item 47: Consider using inline classes 380 Item 48: Eliminate obsolete object references 389 Chapter 8: Efficient collection processing 398 Item 49: Prefer Sequence for big collections with more than one processing step 402 Item 50: Limit the number of operations 419 Item 51: Consider Arrayswith primitives for performance- critical processing 422 Item 52: Consider using mutable collections 425 Dictionary 427
Introduction: Be pragmatic Stories of how popular programming languages originate are often fascinating. The prototype of JavaScript (named Mocha back then) was created in just 10 days. Its creators first considered using Java, but they wanted to make a simpler language for Web designers¹. Scala was created at a university by a scientist, Martin Odersky. He wanted to move some concepts from functional programming into the Java Object Oriented Programming world. It turned out that these worlds are connectable². Java was originally designed in the early ‘90s for interactive televi- sion and set-top boxes by a team called “The Green Team” working at Sun. Eventually, this language was too advanced for the digital cable television industry at the time. It ended up revolutionising general programming instead³. Many languages were designed for a totally different purpose than for what they are used for today. Many originated as experiments. This can be seen in them still today. The differences in the Kotlin story are that: 1. Since the beginning, it was created and designed to be a general-purpose programming language, suitable for large applications. ¹Read about it here: www.en.wikipedia.org/wiki/JavaScript and www.2ality.com/2011/03/javascript-how-it-all-began.html ²Read about it here: https://www.artima.com/scalazine/articles/origins_- of_scala.html ³Read about it here: https://bit.ly/36LMw2z 1
Introduction: Be pragmatic 2 2. The creators of Kotlin are taking their time. Development of Kotlin started in 2010, and the first officially stable version was released in February of 2016. During this period, a lot has 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 ap- plications, and this is reflected in its design. For instance, as opposed to academic or hobbyist languages, it never had ambitions to experiment with new concepts. Kotlin introduced a few new concepts (like property delegation) but the Kotlin team is very conscientious and they prefer to analyze how existing concepts have cooperated and worked for other languages. They are always trying to understand the strengths and weaknesses of other lan- guages and build on them. It is a good strategy for JetBrains since it is the biggest creator of integrated programming environments (IDE). They have a lot of data and knowledge about how various languages are used. They also have specialists that understand each of those 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 and more advanced smart casting and type inference without the necessity of IDE adjustments. The Kotlin team also supports developers by constantly improving IntelliJ warnings and lints. Because of this mechanism, 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 exactly where they are needed. The philosophy of Kotlin Every language has its 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:
Introduction: Be pragmatic 3 • Productivity - application production is fast. • Scalability - with application growth, its development does not become more expensive. It may even get cheaper. • Maintainability - maintenance is easy. • Reliability - applications behave as expected, and there are fewer errors. • Efficiency - the application runs fast and needs fewer re- sources (memory, processor, etc.). We, as a programming community, have tried to satisfy those needs for quite some time. Based on our experiences, we have developed different tools and techniques. For instance, we have learned that automatic testing is very important to prevent errors that are accidentally added to one feature when someone modifies another. There are also rules to follow. For instance, the Single Responsibility Principle from SOLID⁴ helps us with the same problem. Throughout this book, we will mention many such rules. The programming community also found out that there are some less abstract values (from the programmers’ point of view) that support higher level business needs. The Kotlin team collected those values that are important in terms of language design and used them as a point of reference for all design decisions. Those values are: • Safety • Readability • Powerful code reusability • Tool friendliness • Interoperability with other languages I would add another point that is normally not included, but that can be seen in many decisions: ⁴SOLID is a popular set of principles for OOP, introduced and popular- ized by Robert C. Martin.
Introduction: Be pragmatic 4 • Efficiency Those requirements were not something present only at the begin- ning. They have been with Kotlin until today and each change is considered with them in mind. I will also show that they are all very strongly reflected in Kotlin’s design. This was 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 on that. The purpose of this book To really unleash the advantages of Kotlin, we need to use it properly. Knowing features and the standard library (stdlib) is not enough. The main goal of this book is to explain how to use different Kotlin features to achieve safe, readable, scalable, and efficient code. Since this book is written to help developers get better at writing code, it also touches on many 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 manymore. You can also find influence from presentations and Kotlin forums. This book tries to compose as much knowledge about best practices in Kotlin as possible, no matter where it originated. You can call it a collection of best practices; though it differs from classic “Effective X” books because of Kotlin 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 any migration to a better alternative. Most “Effective X” books also ⁵KotlinConf 2018 keynote by Andrey Breslav.
Introduction: Be pragmatic 5 give hints about using some functions 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 left only a few such items. This book is different: it concentrates on higher-level good practices that come from authorities, the Kotlin creators, and from my experience as a developer, consultant, and trainer for international companies worldwide. For whom is this book written? This book is not teaching basics. It assumes that you have enough knowledge and skills to do Kotlin development. If you don’t, I recommend starting first with some resources designed for be- ginners. I recommend Kotlin in Action by Dmitry Jemerov and Svetlana Isakova or the Coursera course Kotlin for Java Developers by Andrey Breslav and Svetlana Isakova. Effective Kotlin is for experienced Kotlin developers. I will assume that even experienced developers might not know some features. This is why I explain some concepts like: • Property • Platform type • Named arguments • Property delegation • DSL creation • Inline classes and functions I want this book to be a complete guide for Kotlin developers on how to become an amazing Kotlin developer. Book design Concepts in the book are grouped into three parts:
Introduction: Be pragmatic 6 • Good code - more general rules about making 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 coincidence that the first chapter is dedicated to safety. I believe that program correctness generally is of the highest priority. Readability is another chapter because the code is not only for a compiler but also for programmers. Even when we work alone, we want code that is readable and self-explanatory. • Code design - this section is for developers creating a project together with other developers, or creating libraries. It is about conventions and setting contracts. It will, in the end, reflect on readability and safety, but all in terms of correct code design. This part is a bit more abstract at the beginning, but thanks to that it can explore topics that are often omitted in books about code quality. This section is also about prepar- ing our code for growth. A lot of items are about being ready for changes in the future. Therefore especially important for developers creating large projects. • Efficiency - this section is for developers that care about code efficiency. Most of the rules presented here do not come at the cost of development time or readability, so they are suit- able for everyone. However, they are particularly important for developers implementing high-performance applications, libraries, or applications for millions. 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
Introduction: Be pragmatic 7 • Chapter 3: Reusability • Chapter 4: Design abstractions • 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, which are like rules. The concept is that items are rules that in most cases need an explanation, but once the idea is clear, it can be triggered just by this title. For instance, the first rule, “Limit mutability”, might be enigmatic for someone who meets it for the first time, but is clear enough to just write in a comment on a code review for someone who is familiar with this book. In the end, suggestions designed this way, with their explanations, should give a clear guideline on how to write good and idiomatic Kotlin code. Chapters organization Chapters often start with the most important concept that is used in other items. A very visible example is Chapter 2: Readability which starts with Item 11: Design for readability, but it is also true for: • Chapter 7: Make it cheap’s first item Item 45: Avoid unneces- sary object creation • Chapter 3: Reusability’s first item Item 19: Do not repeat knowledge • Chapter 1: Safety’s first item Item 1: Limit mutability Chapters can also end with an item that is generally less connected with the rest, but present an important concept that needs to be included, for instance:
Introduction: Be pragmatic 8 • Chapter 1: Safety’s last item is Item 10: Write unit tests • Chapter 2: Readability’s last item is Item 18: Respect coding conventions • Chapter 3: Reusability’s last item is Item 25: Reuse between different platforms by extracting common modules How should this book be read? How should this book be read? The way you like it. Don’t bother jumping between chapters. To some degree, one builds on an- other, but knowledge is presented in such a way that chapters should be understandable independently of others. Having said that, you should read chapters from the beginning as chapters are constructed to make one flow. Choose whatever chapter you want to start with and you can get back to others later. If you feel bored with some item or chapter, skip it. This book was written with pleasure, and it should be read in the same way. Labels It is impossible to write a book for everyone. This book is written primarily for experienced Kotlin developers. Many of them are already familiar with general best practices for programming and they look for Kotlin specific suggestions. Nevertheless, there are some items I decided to include even though they are not Kotlin- specific or they might seem basic for experienced developers. To make it clear which one are those, I added the following labels at the beginning of such items: • Not Kotlin-specific - item does not have Kotlin-specific sug- gestions, 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 (those are items 10, 19, 26, 27, 36).
Introduction: Be pragmatic 9 • Basics - presented suggestions might sound basic for experi- enced Kotlin developers, as they are already covered in other best-practices books and they seem to be understood by the community. If the title seems clear to you, skip such item (those are items 10, 18, 19, 20, 25, 26, 27). • Edu - item is less about best practices and it is dedicated to teaching advanced Kotlin features that are useful for experi- enced Kotlin developers. If you know those features, skip such items (those are items 21, 22, 24, 32) Suggestions If you have any suggestions or corrections regarding this book, send them to contact@marcinmoskala.com
Introduction: Be pragmatic 10 Acknowledgments This bookwould not be so goodwithout great reviewers who highly influenced it by suggestions and comments. I would like to thank all of them. Here is the whole list of reviewers, starting from the most active ones. Márton Braun - A Kotlin enthusiast since version 1.0 of the language, and an aspiring writer, speaker, educator. Android developer and self-proclaimed Kotlin evangelist at Aut- Soft. Android/Kotlin tech editor for RayWen- derlich.com. University student and instruc- tor at BME-VIK, studying computer engineering while teaching Kotlin and Android. Creator of the MaterialDrawerKt and Krate libraries. Occasionally gets addicted to StackOverflow. Márton highly influenced especially chapters 1 to 6 with useful comments, suggestions and corrections. He suggested changes in names of chapters, supported book reorganization, and contributed many important ideas. David Blanc - After graduating in Computer Science from the INSA (a French Engineer- ing school), David started working as a Java engineer for 8 years in various French IT companies, and moved to mobile application development on iOS and Android in 2012. In 2015, he decided to focus on Android and joined i-BP, an IT department of the banking group BPCE, as 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 wording for nearly all chapters. He suggested some good examples and useful
Introduction: Be pragmatic 11 ideas. Jordan Hansen - Jordan has been develop- ing on and off since he was 10. He started developing full time since he graduated from the University of Utah. He started evaluating Kotlin as a viable language since version 0.6 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 organisation. Jordan loves playing tabletop games with his family. Jordan highly influenced most of the book, left many corrections and suggestions also to snippets and titles. He suggested deeper explanation for DSL, and how item dedicated to unit testing can be shortened. He protected correct technical wording. Juan Ignacio Vimberg - The most active reviewer in the toughest part of this book - in the Part 3: Efficiency. Also highly influenced chapters 1 to 4. He suggested to show correct benchmarks, and to describe Semantic Versioning. Kirill Bubochkin - Left perfectly on-point and well thought com- ments all around the book. Fabio Collini - Great review, especially for the Chapter 4 and 5. Inspired point that factory method can be inline in opposition to constructors, and how configuration can be stored in data classes. Bill Best - Important reviewer who influenced chapters 6 to 8, where he left important corrections. Geoff Falk - Helped improving language, grammar, and some code snippets, especially in chapters 2 and 5. Danilo Herrera - Influenced chapter 3, and highly influenced Chapter 4: Abstractions design. Allan Caine - Highly influenced Chapter 5: Objects creation.
Introduction: Be pragmatic 12 Edward Smith - Highly influenced Chapter 6: Class design. Juan Manuel Rivero - Reviewed Chapter 6, 7 and 8. I would also like to thank: • Nicola Corti, for great suggestions and wording improve- ments. • Marta Raźniewska, who made drawings starting each section. • Most active alpha testers: Pablo Guardiola, Hubert Kosacki, Carmelo Iriti and Maria Antonietta Osso. • Everyone who helped this book by sharing news about it or sharing feedback and feelings with me.
Part 1: Good code 13
Chapter 1: Safety Why do we decide to use Kotlin in our projects instead of Java, JavaScript or C++? Developers are often bought by conciseness or amazing Kotlin features. For business, as I found out, the truly convincing argument is Kotlin safety - how its design eliminates potential application errors. You don’t need to have any experience with development to get upset when the application you use crashes, or when there is an error on a website that does not let you check out after you spent an hour collecting products into a basket. Having fewer crashes makes the lives of both users and developers better, and it provides 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 important best practices for safety in Kotlin. We’ll see how Kotlin 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. 14