📖A philosophy of software design
- authors
- Ousterhout, John
- year
- 2018
The most fundamental problem in computer science is problem decomposition (p. vii)
Complexity → Time-adjusted complexity definition where — complexity of part — time developers spend on this part
“Isolating complexity in a place where it will never be seen is almost as good as eliminating the complexity entirely.” (p.6) → Time-adjusted complexity justifies pushing the complexity downward
Symptoms of complexity: (pp.7-8)
change amplification
cognitive load
the total number of things you need to keep in the head
unknown unknowns
when you have to know something but you don’t know that you have to
absolutely the worst—you can’t deal with it
Causes of complexity
dependency
changes in one part require changes in other parts
causes change amplification and cognitive load
obscurity
something is harder to understand than it needs to be
causes cognitive load and unknown unknowns
complexity is incremental
similar to performance issue with no high cost centers
same way out
“tactical tornadoes” are the fastest to produce features but others have to clean up after them (p.14)
invest 10-20% of time (p.15)
p.21
An abstraction is a simplified view of an entity, which omits unimportant details.
A smell: pass-through methods (methods that just call to other methods, passing the same parameters)
p.55
Most modules have more users that developers, so it is better for the developers to suffer than the users.
If class has general-purpose methods, it should provide general-purpose methods only. Specializations should be handled in different class. (pp.62,64)
red flag: conjoined methods. “it should be possible to understand each method independently” (without looking what other method does) (p.72)
exceptions
exceptions encourage proliferation of exceptions/error conditions, and error conditions are hard to deal with (p.78)
90% of all failures is caused by incorrect error handling (p.77)
exceptions lead to “the more errors detected, the better” thinking. but more exceptions complicate system (p.78)
exceptions in interface make class shallower. a class that handles its own error conditions is deeper (re: Deep/shallow modules)
how to deal with exceptions:
push down (mask)
request-level handler (clean up, serve next request)
crash
comments
comments can “provide” abstraction. p.101
code is too low-level to provide useful abstractions (p.110)
write comments before writing code (§15)
it’s more fun
it helps design better software (long complex comments may serve as a red flag)
you’re most likely to write useful comments that do not repeat code if you write comments first
in C++, keep comments in .cpp, not .h. This way, it’s more likely the comments will be updated when code changes. (p.137)
if commit message is important, duplicate it in code comment (p.138)
p.128
The greater the distance between a name’s declaration and its uses, the longer the name should be.
—Gerrand
TDD is tactical programming (p.155)
do I agree?
“incremental” performance issues (“death by a thousand cuts”) p.159