00:00:00 - 01-Part1 - In theory 00:01:05 - 02-Ch1 Code quality 00:08:55 - 03-Ch1 The goals of code quality 00:20:48 - 04-Ch1 The pillars of code quality 00:31:07 - 05-Ch1 Make code hard to misuse 00:39:49 - 06-Ch1 Make code testable and test it properly 00:50:32 - 07-Ch2 Layers of abstraction 00:56:09 - 08-Ch2 Why create layers of abstraction 01:02:28 - 09-Ch2 Layers of code 01:09:58 - 10-Ch2 Classes, Part1 01:17:07 - 11-Ch2 Classes, Part2 01:23:45 - 12-Ch2 Interfaces 01:30:12 - 13-Ch2 When layers get too thin 01:37:47 - 14-Ch3 Other engineers and code contracts 01:46:50 - 15-Ch3 How will others figure out how to use your code 01:53:40 - 16-Ch3 Code contracts 02:00:02 - 17-Ch3 Don’t rely too much on small print 02:09:15 - 18-Ch3 Checks and assertions 02:18:23 - 19-Ch4 Errors 02:29:26 - 20-Ch4 Robustness vs. failure 02:37:00 - 21-Ch4 Don’t hide errors 02:45:06 - 22-Ch4 Ways of signaling errors 02:54:06 - 23-Ch4 Explicit - Nullable return type 03:02:46 - 24-Ch4 Implicit - Promise or future 03:09:31 - 25-Ch4 Signaling errors that a caller might want to recover from 03:15:12 - 26-Ch4 Arguments for using explicit techniques 03:26:30 - 27-Part2 - In practice 03:27:57 - 28-Ch5 Make code readable 03:33:03 - 29-Ch5 Use comments appropriately 03:40:58 - 30-Ch5 Don’t fixate on number of lines of code 03:46:21 - 31-Ch5 Stick to a consistent coding style 03:56:19 - 32-Ch5 Make function calls readable 04:04:06 - 33-Ch5 Avoid using unexplained values 04:09:56 - 34-Ch5 Use anonymous functions appropriately 04:18:41 - 35-Ch5 Solution - Break large anonymous functions into named functions 04:24:41 - 36-Ch6 Avoid surprises 04:31:10 - 37-Ch6 Solution - Return null, an optional, or an error 04:39:32 - 38-Ch6 Use the null object pattern appropriately 04:47:09 - 39-Ch6 More complicated null objects can cause surprises 04:52:49 - 40-Ch6 Avoid causing unexpected side effects 05:03:16 - 41-Ch6 Beware of mutating input parameters 05:08:35 - 42-Ch6 Avoid writing misleading functions 05:15:15 - 43-Ch6 Future-proof enum handling 05:23:31 - 44-Ch6 Beware of the default case 05:30:23 - 45-Ch7 Make code hard to misuse 05:38:44 - 46-Ch7 Solution - Set values only at construction time 05:47:05 - 47-Ch7 Consider making things deeply immutable 05:56:27 - 48-Ch7 Avoid overly general data types 06:07:23 - 49-Ch7 Dealing with time 06:18:40 - 50-Ch7 Have single sources of truth for data 06:24:31 - 51-Ch7 Have single sources of truth for logic 06:31:41 - 52-Ch8 Make code modular 06:40:06 - 53-Ch8 Design code with dependency injection in mind 06:47:49 - 54-Ch8 Beware of class inheritance 06:56:54 - 55-Ch8 Solution - Use composition 07:07:00 - 56-Ch8 Classes should care about themselves 07:18:01 - 57-Ch8 Beware of leaking implementation details in return types 07:24:25 - 58-Ch8 Beware of leaking implementation details in exceptions 07:32:55 - 59-Ch9 Make code reusable and generalizable 07:44:42 - 60-Ch9 Beware of global state 07:56:18 - 61-Ch9 Use default return values appropriately 08:04:27 - 62-Ch9 Keep function parameters focused 08:15:24 - 63-Part3 - Unit testing 08:16:31 - 64-Ch10 Unit testing principles 08:23:27 - 65-Ch10 What makes a good unit test 08:33:28 - 66-Ch10 Well-explained failures 08:39:01 - 67-Ch10 Focus on the public API but don’t ignore important behaviors 08:50:10 - 68-Ch10 Test doubles 08:59:03 - 69-Ch10 Mocks 09:05:35 - 70-Ch10 Mocks and stubs can be problematic 09:13:11 - 71-Ch10 Fakes 09:23:16 - 72-Ch10 Pick and choose from testing philosophies 09:28:58 - 73-Ch11 Unit testing practices 09:40:54 - 74-Ch11 Avoid making things visible just for testing 09:52:37 - 75-Ch11 Test one behavior at a time 10:00:45 - 76-Ch11 Use shared test setup appropriately 10:09:47 - 77-Ch11 Shared configuration can be problematic 10:18:37 - 78-Ch11 Use appropriate assertion matchers 10:24:13 - 79-Ch11 Use dependency injection to aid testability 10:33:14 - 80-Appendix B. Null safety and optionals
Hide player controls
Hide resume playing