Tidy First? - Kent Beck
Note: These are my own notes and observations upon reading the book. They serve as a reminder, when I need to rehash some content. I own none of the content.
I. Tidyings
1. Guard Clause
Return early -- reduced mental complexity.
2. Dead Code
Just remove it
3. Normalize Symmetries
Write code that does the same thing in the same way
4. New Interface, Old Implementation
If you need a new interface for something, feel free to add it and make it call the old implementation. You can refactor the old implementation afterwards.
5. Reading Order
Prioritize for ordering files in the order they should be read, where possible. Don't leave the insightful component that makes everything make sense at the end of the file.
6. Cohesion Order
Put coupled things next to each other. Decoupling might be best thing to do, but it's way more expensive.
7. Move Declaration and Initialization Together
8. Explaining Variables
Extract big expressions into variables
9. Explaining Constants
Extract fixed values into named constants
10. Explicit Parameters
Don't pass values as untyped collections. Make it typed, explicit parameters
11. Chunk Statements
Add blank lines in between logical chunks
12. Extract Helper
Extract functions with functionality when it makes sense (related to above point).
13. One Pile
If code is hard to read because it's scattered, inlining in 1 pile might help. Symptoms:
- long repeated argument lists
- repeated code, especially repeated conditionals
- poor naming of helper routines
- shared mutable data structures
14. Explaining Comments
Whenever you have an "Aha!" moment, just write it down.
15. Delete Redundant Comments
Comments that = the code, are useless
II. Managing
16. Separate Tidying
Structure (tidying) and behaviour changes should go in separated PRs.
17. Chaining
One tidying can lead into another.
18. Batch Sizes
Size influences review. Bias for small batch sizes
19. Rhythm
minutes-to-hour activity. If it's more, rethink your approach.
20. Getting Untangled
You made some progress and you figure out there might be a better way to untangle it. Always bias starting over -- good for you, good for reviewers, good for future readers.
21. First, After, Later Never
Refactor... Never:
- you're never changing this code again
- there's nothing to learn by improving the design Later:
- you have a big batch of tidying to do without immediate payoff
- there's eventual payoff for completing the tidying
- you can tidy in little batches After:
- waiting until next time to tidy first will be more expensive
- you won't feel a sense of completion if you don't tidy after First:
- it will pay off immediately, either in improved comprehension or in cheaper behavior changes
- you know what to tidy and how
III. Theory
22. Beneficially Relating Elements
Structure of the system is:
- element hierarchy
- relationship between elements
- benefits created by these relationships (invokes, publishes, listens, refers, etc.)
23. Structure & Behavior
You can create value through both. Behavior is evident, but structure not so much. Optionality creates values and structure leads to optionality (a machine that turns 1$ in 10$ is less desirable than either a machine that turns 10$ into 100$ or 1$ into 20$). The more options you can exercise, the more value you created.
24. Economics: Time Value and Optionality
- a dollar today is worth more than a dollar tomorrow - earn sooner and spend later
- options are better than things - create options in face of uncertainty
25. A Dollar Today > A Dollar Tomorrow
Pay 10M $ today and in 10 years see 20M $ is less attractive to get 12M $ today and in 10 years pay 10M $. The case is made for getting value earlier and spending later => tidy after over tidy first
26. Options
What behavior can I implement next?
- has value in it's own even before implementing it
- the more behaviors, the more value As long as there are a lot of options, I don't have to know which is the most valuable. The more uncertain my predictions of value, the greater the value of the option is (vs just implementing it).
A few notes to think of:
- the more volatile the value of a potential behavior change, the better
- the longer you could develop, the better
- the cheaper you could develop in the future, the better
- the less design work you could do to create an option, the better
27. Options Versus Cash Flows
Tidy first when:
cost(tidying) + cost(behavior change after tidy) < cost(behavior change without tidying)
It gets complicated when:
cost(tidying) + cost(behavior change after tidy) > cost(behavior change without tidying)
Use your gut feeling, knowing you are going counter to your economic incentives. A good rule of thumb is: "There's more good stuff here, but I need to tidy to be able to see it."
28. Reversible Structure Changes
Treat reversible structure changes lightly. Some changes are not as reversible (propagating a value in the entire codebase or extracting into a service). Treat those with closer attention and put them under bigger scrutiny.
29. Coupling
Expensive programs have one property in common: changing one element requires changing other elements. Cheap programs tend to require localized changes. Coupling drives the cost of software. Coupling has two scary properties:
- 1 to N - an element can be coupled with any number of other elements
- cascading - once a change has rippled from one element to another, that change can trigger another round of changes and so on
30. Constantine's Equivalence
cost(software) ~= cost(change)
Why is slope of cost growth much steeper after release? The existing system has started to create friction:
- worry about backwards compatibility
- worry about production stability
- worry about all the way one change might break unrelated features "The five biggest storms cause more damage than ten thousand small storms."
cost(change) ~= cost(big changes)
cost(big changes) ~= coupling
which results in:
cost(software) ~= cost(change) ~= cost(big changes) ~= coupling
Decoupling isn't free and is subject to trade-offs.
31. Coupling Versus Decoupling
You are always faced with a choice: pay the cost of coupling or pay the cost of decoupling. Unproven observation: "The more you reduce coupling for one class of changes, the greater the coupling becomes for other classes of changes."
32. Cohesion
- Coupled elements should be subelements of the same containing element.
- Elements that aren't coupled should go elsewhere.
Conclusion
- Cost - will tidying make cost smaller, later, or less likely?
- Revenue - will tidying make revenue larger, sooner, or more likely?
- Coupling - will tidying make it so I need to change fewer elements?
- Cohesion - will tidying make it so the elements I need to change are in a smaller, more concentrated scope? "Most important, though, is you. Will tidying bring peace, satisfaction, and joy to your programming? Maybe some. This is important because if you are your best self, you are a better programmer. You can't be your best self if you're always rushing, if you're always changing code that's painful to change."