Reading notes on “Tidy First?” For looking back later, I’m loosely leaving what stuck with me and my own impressions.
Perspectives You Should Understand After Reading (From the Preface)
- The basic difference between behavioral changes and structural changes
- A way of thinking for a single programmer to alternate between investing in structure and investing in behavior
- The basic theory of why software design works, and the forces that influence design
- That tidying first can improve your own programming experience
- Starting large changes with small, safe steps
- Preparing for design while being aware that it is an activity involving people with various motivations
Empirical Software Design
In software design, “what” to design is often debated.
- What is a good size for a service?
- What is a good size for a repository?
- Events vs. explicit service calls
- Objects vs. functions vs. imperative code
Part 1: Tidying
A catalog of techniques. The ones I want to note down.
- Guard clauses
- There are preconditions to keep in mind before getting into the details of the code
- Dead code
- Delete it. Code that never runs simply gets deleted
- (impression) As a result of AI writing logic while looking only at parts, several pieces of code that never run can get generated. After having AI write it once, add a check by AI or a human again
- Normalize how things are written
- The same problem can be solved in a different form depending on the time or person tackling it
- Making a transparent interface is the smallest essential unit in software design. It makes changes easy when you want to tweak behavior a bit
- Code test-first. Start from a test that must succeed
- Order of cohesion
- You sometimes notice you have to make changes to spots scattered throughout the code in order to change behavior
- Rearrange the order of the code so that the elements to be changed become adjacent
- Bring variable declaration and initialization to the top
- Explaining variables
- Expressions grow. Even starting small, they keep growing
- Attach explanations to expressions so they can be understood in small pieces. Drop the hard-won understanding into the code
- Explaining constants
- Stop using magic numbers
- Break statements into smaller pieces
- Extract helpers
- Extract code blocks whose interaction with other code is limited as helper routines
- Splitting into too many small parts makes code hard to understand. Signs to look for:
- Long, repetitive argument lists
- Repeated code and conditionals
- Poor naming of helper routines
- Shared mutable data structures
- Explaining comments
- Write, in explaining comments, what cannot be read from the code
- Delete redundant comments
- “Returns x” →
return x. No benefit. It only wasted the reader’s time
- “Returns x” →
(impression) It might be good to put these perspectives into an AI SKILL.
Part 2: Management
When to start tidying / when to stop / how to combine structural and behavioral changes → it depends.
- Combining or splitting pull requests is a trade-off
- A huge PR makes the overall picture easy to see, but is too large for reviewers to return useful feedback
- A small PR invites detailed feedback, but there is also a risk of getting caught up in trivia
- Beware of changing too much, too fast. The failure of one tidying costs more than the success of a chain of tidyings
Two Things to Consider Before Deploying
- How much to tidy. How much structural change is needed to support the next behavioral change. Tidying addresses immediate needs, not the far distant future
- How much tidying makes it easy to integrate and deploy
→ Reduce the cost of review and keep the batch size small to reduce the cost of tidying.
Tidy First / Tidy Later / Do Not Tidy
- For a truly static system, “if it isn’t broken, don’t fix it” is reasonable
- You can still tidy even if you put it off
- Tidy again = picking up later what you would do if you had enough time
- Tidying again reduces the tax of being cluttered
Questions for deciding whether to do it first:
- How hard is it to change this cluttered spot? If tidying does not make the change easier, do not tidy first
- How soon can you gain the benefit of tidying? Even while still reading and understanding, tidying speeds up understanding. If so, tidy first
- How is this tidying amortized? If it will be changed only once, keep tidying modest. If there is a return every week for years, tidy
- How confident are you in the tidying? Do not be swept along by guesses. “This spot is cluttered. If this were gone, the change would be easy”
Summary (Four Quadrants)
- Do not tidy: will never change again / nothing to learn from the design
- Tidy again: there is a large chunk with no immediate return / there is an eventual return once complete / it can be done bit by bit
- Tidy later: waiting until the future would cost more / you do not get a sense of completion
- Tidy first: there is an immediate return (understanding improves, behavior becomes easier to change) / you know what and how to tidy
Structure and Behavior
Solid structure is made of parts.
- Organelle → organ → organism
- Atom → molecule → crystal
- Software: token → expression → statement → function → object/module → system
What “the structure of a system” means:
- A hierarchy of elements
- The relationships among elements
- The benefits that arise from those relationships
This lets you distinguish structure and behavior more clearly.
Words That Stuck With Me
- You can keep the kitchen beautiful even while cooking
- Software design is preparation for behavioral change. Today’s design is a premium for an “option” that lets you “buy” tomorrow’s behavioral change
- Most design decisions can be easily reverted. There is little value in avoiding mistakes, so you should not invest much for that
- A costly program requires changing other elements just to change one element. A low-cost program gets by with a local change
- To lower software’s cost, reduce coupling. But decoupling is not free either, and there is a trade-off relationship