Cheat Sheet
Write code like it is a recipe (because it is)
Start by constructing the long-lived service objects, and wiring them all together. Primary execution happens after that. Functions behave like paragraphs: the longer they run on, the easier it is to become lost.
Remember to separate “new”
Often, going through the exercise of keeping construction logic and business logic apart seems unnecessary or a waste of time, or perhaps seems to add complexity. However, as the codebase grows, somehow it becomes more and more difficult to change, more and more difficult to understand, as a result of coupled construction and business logic.
Most “if” statements (conditional logic) can be replaced with polymorphism
Every if statement creates a branch in the execution path that the code could take, and each branch and its implications must be fully understood. Branching logic has a high cognitive load: it is difficult to reason about multiple things at the same time.
Documentation is vital
- Document the intent behind a decision (i.e. the “why”), not what the code does
- Prefer doc blocks to inline comments
- Ensure documentation is updated to remain correct when updating code
Unit tests must be useful
- Contract tests and complexity tests should be permanent, other unit tests should be temporary
- There are four types of test doubles: dummies, stubs, mocks, and fakes
- Adhering to the rules described in this book should make unit testing straightforward
Common problems when refactoring
- Nested control blocks, such as for loops, if statements, switch statements, try|catch blocks, etc.
- Nested function calls, like: A(B(C(D(foo))))
- Shorthand or meaningless variables names: a, m1 , myVar, etc
- Unnecessary variable mutation (changing the value of a variable)
- Global variables
- Excessive in-line comments, explaining what a line of code does instead of why it does it
- Lack of documentation about expected inputs and outputs
- Variables that seem to be re-used for multiple purposes Inconsistent style or naming