A Philosophy of Software Design Part 5 - Boundaries and Errors Are Design Choices
A Philosophy of Software Design treats software design less as architectural theater and more as the daily work of managing complexity. This part covers Chapter 9 Better Together Or Better Apart? and Chapter 10 Define Errors Out Of Existence. It uses only short key phrases from the source and turns the reading into summary, interpretation, and application.
The guiding question is: Where should a good design split, and where should it join?
This is part 5 of a ten-part reading of A Philosophy of Software Design. The scope is Chapter 9 Better Together Or Better Apart? and Chapter 10 Define Errors Out Of Existence.
The operating principle remains: book notes are storage; insight cards are currency.
L0 · Entry
- Core sentence: Module boundaries and error handling should both reduce the number of cases users must understand.
- Why read this: As AI tools and automation make code faster to produce, I want sharper standards for code that remains understandable and changeable.
- Initial hypothesis: Splitting code and handling errors often look like separate topics. Here they become one question: how many cases does the interface expose to users?
- Author context: John Ousterhout is a computer scientist known for work in operating systems, distributed systems, Tcl/Tk, and software design education at Stanford.
- Scope: Chapter 9 Better Together Or Better Apart? and Chapter 10 Define Errors Out Of Existence
L1 · Captures
“better together”
Shared information can make joining simpler than splitting. Separation rules create complexity when applied without context. ^q01
“define errors out of existence”
This favors removing error states instead of adding more error-handling code. Preventing exceptions can be deeper than catching them. ^q02
“special cases”
This points to cases that widen the interface. The first question is whether a special case can become part of the general rule. ^q03
This public note does not reproduce long source passages. It uses chapter-level concepts and short phrases as anchors, then provides transformative summary and commentary.
L2 · Map
| # | Range | Summary | Main claim |
|---|---|---|---|
| 1 | Joining | Keep code together when knowledge is shared or the interface becomes simpler | Separation creates information movement cost |
| 2 | Splitting | Separate general-purpose code from special-purpose code | Not all coupling is bad, and not all separation is good |
| 3 | Eliminating duplication | Duplication caused by splitting can signal a wrong boundary | Duplicated knowledge may reveal boundary failure |
| 4 | Exception complexity | Exceptions increase paths outside the normal flow | Error handling is part of the interface surface |
| 5 | Removing errors | Impossible states reduce handling code | Design can replace some validation work |
Argument in one paragraph:
Module boundaries and error handling should both reduce the number of cases users must understand. Splitting code and handling errors often look like separate topics. Here they become one question: how many cases does the interface expose to users? In practice, this moves review questions from “does it work?” toward “what must the next reader know in order to change it safely?” Design is not a separate ceremony; it is embedded in names, boundaries, exceptions, comments, layers, and performance choices.
L3 · Insight Cards
- A Philosophy of Software Design - I5.1 Module boundaries should follow the flow of shared knowledge, not the number of objects
- A Philosophy of Software Design - I5.2 Error handling is an interface surface problem before it is a failure response problem
- A Philosophy of Software Design - I5.3 Designing away special cases reduces branching in the caller’s mind
L4 · Production Board
- Blog draft: Part 5 as “Boundaries and Errors Are Design Choices”
- Code review question: Where should a good design split, and where should it join?
- Insight card: Module boundaries should follow the flow of shared knowledge, not the number of objects
L5 · Review
- Connections: This connects to domain modeling: making impossible states unrepresentable moves error handling from response to design.
- Open questions:
- Where does this part’s red flag appear most clearly in my current codebase?
- What check would an AI coding agent need in order to apply this principle reliably?
- Final takeaway: A good boundary is not a decorative line through code; it is a device for reducing the user’s cases.
댓글
GitHub 계정으로 의견을 남길 수 있습니다. 댓글은 GitHub Discussions에 저장됩니다.