Chapter 3: Working Code Isn't Enough (Strategic vs. Tactical Programming)
Core Idea
Section titled “Core Idea”Getting code working is not the goal. The goal is a great design that also happens to work. Strategic programming invests a steady 10–20% of development time in design, and that investment pays for itself within months.
Frameworks Introduced
Section titled “Frameworks Introduced”- Tactical vs. strategic programming:
- Tactical programming: “your main focus is to get something working.” Each task adds a little complexity or a small kludge to finish faster. It is short-sighted, and once you start down this path it is hard to change.
- Strategic programming: “Your primary goal must be to produce a great design, which also happens to work.” Most code is written by extending existing code, so your most important job is to make future extensions easy.
- The investment mindset: accept being a little slower now to be faster later.
- Proactive investments: try a couple of alternative designs for each new class and pick the cleanest; imagine a few ways the system might need to change and check that your design handles them; write good documentation.
- Reactive investments: when you discover a design problem, don’t ignore it or patch around it. Take a little extra time to fix it.
- How much to invest: 10–20%.
- How: make lots of small investments continuously, not one big up-front design. Spend about 10–20% of total development time on them.
- What happens: early projects take 10–20% longer. Within a few months you develop at least 10–20% faster than you would tactically, and the investments become free because past benefits cover future costs.
- The reverse: tactical programmers finish first projects 10–20% faster, then become at least 10–20% slower for the rest of the system’s life. People who have worked in a degraded code base say poor code quality slows development by at least 20%.
Key Concepts
Section titled “Key Concepts”- Tactical tornado: a prolific programmer who “pumps out code far faster than others but works in a totally tactical fashion.” Management may treat them as heroes, but they leave a “wake of destruction.” The engineers who clean up after them are “the real heroes,” though they appear slower.
- Working code isn’t enough: the first step to becoming a good designer is realizing this.
- Continuous small investments: the ideal design emerges in pieces as you gain experience, so investment has to be continual.
- Slippery slope of the crunch: postponing cleanups until after the current crunch, when another crunch always follows.
Mental Models
Section titled “Mental Models”- Think of design work as an investment with a quick payback, not as a cost. Figure 3.1 shows total progress over time: the tactical curve rises faster at first and then flattens, while the strategic curve starts slower, crosses it, and keeps rising. The author notes the figure is qualitative only, with no empirical measurements behind the curve shapes.
- Think of investment as something to do today, not tomorrow. “The longer you wait to address design problems, the bigger they become.”
- Use hiring as part of the cost model. The best engineers care about good design and cost little more than mediocre ones. A messy code base becomes known and makes recruiting harder, which degrades the code further.
Anti-patterns
Section titled “Anti-patterns”- Small kludges to finish faster: each one seems reasonable, and together they produce a mess.
- Patching around problems: patches create more complexity, which needs more patches.
- Planning to hire engineers later to clean up: startups that expect success to pay for a cleanup find that “once a code base turns to spaghetti, it is nearly impossible to fix.” The payoff from design comes quickly, so tactical work may not even speed up the first release.
- Delaying cleanup until after the crunch: delays become permanent, and the team’s culture slides into the tactical approach.
Rules of Thumb (author’s wording)
Section titled “Rules of Thumb (author’s wording)”- “The first step towards becoming a good software designer is to realize that working code isn’t enough.”
- “It’s not acceptable to introduce unnecessary complexities in order to finish your current task faster.”
- “Good design doesn’t come for free.”
- “The most effective approach is one where every engineer makes continuous small investments in good design.”
Worked Example
Section titled “Worked Example”Startups: Facebook versus Google and VMware.
- Facebook (tactical). Its motto was “Move fast and break things.” New graduates pushed commits to production in their first week, with few rules. Engineers felt empowered, but much of the code became unstable and hard to understand, with few comments or tests.
- The correction. Facebook changed its motto to “Move fast with solid infrastructure” to encourage investment in design. The author notes it “remains to be seen” whether the accumulated problems can be cleaned up, and that Facebook’s code is probably no worse than average for a startup.
- Google and VMware (strategic). They grew up at the same time and emphasized high-quality code and good design. They built reliable systems for complex problems, and their strong technical cultures let them hire top talent that few others could compete for.
- Conclusion. A company can succeed either way, “However, it’s a lot more fun to work in a company that cares about software design and has a clean code base.”
Applying the 10–20% rule to one task (an illustration, not from the book). You are adding a feature to a class whose interface already forces callers to know too much. Tactically, you add one more special-case parameter and move on. Strategically, you spend some extra time on the task to simplify the interface so the new feature fits cleanly (a reactive investment), and you sketch two designs before choosing one (a proactive investment, ch11).
Key Takeaways
Section titled “Key Takeaways”- Make a great design your primary goal; working code is required but not sufficient.
- Budget about 10–20% of development time for design investments, every week.
- Fix design problems when you find them, instead of patching around them.
- Don’t use a crunch as a reason to defer cleanup; there will always be another crunch.
- Don’t reward tactical tornadoes. Recognize the engineers who clean up after them.
Connects To
Section titled “Connects To”- Ch 2: complexity is incremental, which is why tactical shortcuts add up.
- Ch 11: “Design it twice” is a concrete proactive investment.
- Ch 15: writing comments first is another investment that pays back during design.
- Ch 16: staying strategic when modifying existing code.
- Ch 19: agile development’s risk of becoming tactical.