# 📖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 $C = \sum_{p} c_p t_p$ where $c_p$ — complexity of part $t_p$ — time developers spend on this part

• Symptoms of complexity: (pp.7-8)

• change amplification

• 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.

• Deep/shallow modules
• 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:

• request-level handler (clean up, serve next request)
• crash

• 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