cover image for A Philosophy of Software Design

A Philosophy of Software Design

John Ousterhout

8/10
A fantastic book that details a lot of what make a good developer vs a bad one and what patterns, philosophies and general ideas lead to problem in large code bases. So cool to seem many ideas I've had to struggle with and learn on my own be incorporated and de-mystified. Plus a bunch I didn't even know.
  • Complexity makes code hard to understand and/or modify
  • Change amplification: requireing changes in many places for repeated code
  • Cognative load: have to remember/learn lots required info
  • Unknown Unknowns: unclear what code must be modified or what info is needed to complete, hard coded exceptions that need to be changed with a global var (color)
  • Obscurity: important info isn't obvious
  • Dependencies: other code must be understood and/or modified as well (can be done well sometimes)
  • Constantly invest in good design/solving tech debt, rather than solving bugs/features ASAP
  • Interfaces should be simple/clear, Implementations should be deep and complex
  • Red Flag: information leakage, when 2 classes both need the same knowledge, like a particular file format
  • Temporal decomposition: don'tdivide based on time, like having to have a read, then a write sequentially. Both might need to be modified if something like file format changes
  • Red flag: Overexposure, if an API forces users to configure rarely used features and learn configuration and flags for it, it increases cognative load which is bad. Instead just have defaults and optional flags
  • Be general purpose but easy to use for current case. eliminate or abstract ouf or push lwer/higher special cases
  • Red Flag: Pass through Method, A method that just passes args to a different function. Usually a sign that 2 classes/function don't have distinct enough roles/responsibbilities
  • When developing modules, look to take a bit of extra suffering yourself for ease of your users
  • Bring code together when: They share info, they are used together, they overlap conceptually and their is a high level category that encapsulates both, its hard to understand one without the other
  • Red Flag: Special General Mixture, Occurs when general purpose mechanism also contains code specialized for a particular use of that mechanism
  • The desicision to split modules is based on complexity, choose for fewest, dependencies, best info hiding and deepest interfaces
  • When commenting, Units for variables, inclusive or exclusive boundaries, null implies?, freed? and who is responsibles, are their certain properties that are always true (like list always contains 1 entry)
  • Comments: high level, what is code trying to do as simply stated as possible, why/when is this code executed
  • Comments shoudl explain what/why not how
  • If its hard to pick a concise clear name that s a red flag for design
  • Write comments first as part of design
  • Don't duplicate documentation instead poitn to a global design dock with section that refer to that one point, useful for distributed system or calls and API's that always need to match
  • For agile, increment of development should be abstractions not features
  • The issue with Test Driven Development is that it focuses on getting specific features working rather than the best design
  • When thinking about performance consider what most expensive in the system, usually (Network communication, I/O to secondary storage, dynamic memory allocation, cache misses)
  • When trying to improve performance always measure before and after
;