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?
How to use this note 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
Short phrase · design "better together" Shared information can
make joining simpler than splitting.
Separation rules create complexity when applied without context.
Short phrase · design "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.
Short phrase · design "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.
Copyright boundary 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 Outputs 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.