Introduction: Be pragmatic
- Who is this book for?
- Code Sources
Part 1: Good code
Chapter 1: Safety
- Item 1: Limit mutability
- Item 2: Eliminate critical sections
- Item 3: Eliminate platform types as soon as possible
- Item 4: Minimize the scope of variables
- Item 5: Specify your expectations for arguments and state
- Item 6: Prefer standard errors to custom ones
- Item 7: Prefer a nullable or
Resultresult type when the lack of a result is possible - Item 8: Close resources with
use - Item 9: Write unit tests
Chapter 2: Readability
- Item 10: Design for readability
- Item 11: An operator’s meaning should be consistent with its function name
- Item 12: Use operators to increase readability
- Item 13: Consider making types explicit
- Item 14: Consider referencing receivers explicitly
- Item 15: Properties should represent a state, not a behavior
- Item 16: Avoid returning or operating on
Unit? - Item 17: Consider naming arguments
- Item 18: Respect coding conventions
Part 2: Code design
Chapter 3: Reusability
- Item 19: Do not repeat knowledge
- Item 20: Do not repeat common algorithms
- Item 21: Use generics when implementing common algorithms
- Item 22: Avoid shadowing type parameters
- Item 23: Consider using variance modifiers for generic types
- Item 24: Reuse between different platforms by extracting common modules
Chapter 4: Abstraction design
- Item 25: Each function should be written in terms of a single level of abstraction
- Item 26: Use abstraction to protect code against changes
- Item 27: Specify API stability
- Item 28: Consider wrapping external APIs
- Item 29: Minimize elements’ visibility
- Item 30: Define contracts with documentation
- Item 31: Respect abstraction contracts
Chapter 5: Object creation
- Item 32: Consider factory functions instead of constructors
- Item 33: Consider a primary constructor with named optional arguments
- Item 34: Consider defining a DSL for complex object creation
- Item 35: Consider using dependency injection
Chapter 6: Class design
- Item 36: Prefer composition over inheritance
- Item 37: Use the data modifier to represent a bundle of data
- Item 38: Use function types or functional interfaces to pass operations and actions
- Item 39: Use sealed classes and interfaces to express restricted hierarchies
- Item 40: Prefer class hierarchies instead of tagged classes
- Item 41: Use enum to represent a list of values
- Item 42: Respect the contract of
equals - Item 43: Respect the contract of
hashCode - Item 44: Respect the contract of
compareTo - Item 45: Consider extracting non-essential parts of your API into extensions
- Item 46: Avoid member extensions
Part 3: Efficiency
Chapter 7: Make it cheap
- Item 47: Avoid unnecessary object creation
- Item 48: Consider using object declarations
- Item 49: Use caching when possible
- Item 50: Extract objects that can be reused
- Item 51: Use the inline modifier for functions with parameters of functional types
- Item 52: Consider using inline value classes
- Item 53: Eliminate obsolete object references
Chapter 8: Efficient collection processing
- Item 54: Prefer Sequences for big collections with more than one processing step
- Item 55: Consider associating elements to a map
- Item 56: Consider using groupingBy instead of groupBy
- Item 57: Limit the number of operations
- Item 58: Consider Arrays with primitives for performance-critical processing
- Item 59: Consider using mutable collections
- Item 60: Use appropriate collection types
