Key Points Of A Philosophy Of Software Design
"It's a great feeling to discover a solution that is both simple and powerful. A clean, simple and obvious design is a beautiful thing"
This is about the book "A Philosophy Of Software Design" by John Ousterhout that I read at some point and wanted to save some key thoughts in a succinct and structured way. I found the principles described in the book really thoughtful and applicable to the real life - and even though I have some reservations about certain points, the difference of opinions does not make this book any less useful or relevant (perhaps the opposite, even more so).
Key thoughts (in no particular order)
- Make deeper modules, hiding technical details inside and exposing simple interface with minimal required functionality. Also use many defaults so only required values would be provided.
- Do not use order of operations as a principle for module structure, instead focus on what pieces are required to perform an operation and put them together.
- Generalise - the less specific method user needs to remember the better. If method is designed for just one case, maybe or can be merged with another similar functionality?
- Do not over generalise - trying to build a very generic interface leads to more cognitive load, more complexity and harder to maintain/easier to break systems.
- No simple pass through method, they indicate that something is wrong with abstraction.
- "Most modules have more users than developers, so it's better for the developed to suffer thant the users" :)
- It's more important to have a simple interface than a simple implementation.
- "Pull complexity downwards" - meaning to the lower implementation level, where fewer people would need to deal with it.
- Don't overdo things, keep abstractions native to a specific area at that very level only.
- "Define errors out of existence", as error handling causes unnecessary complicated code, and "overall, the best way to reduce bugs is to make software simpler". Just die if it's bad, if it's important enough. (IMO the best way is to throw typed exceptions and catch them at higher level where they could be converted in interface/user-visible errors).
- Design it twice - outline pros and cons of the first approach, check how it would work in a few month/year and see if you can come up with something better. "Eventually, everyone reaches a point where your first ideas are not good enough"; also, "it isn't that you aren't smart; it's that the problems are really hard!".
- "The process of writing comments, if done correctly, will actually improve a system's design". Also, "inadequate documentation creates a huge and unnecessary drag on software development" and "if I must read the code of a method on order to use it, there is no abstraction". Inline comments should describe things that are not immediately clear from the code and not repeat the code itself.
- If finding a simple yet descriptive and clear name for a thing is hard then maybe the design of the thing itself is not clear.
- Names should be clear, common, consistent and same name should server same purpose.
- Readability should be determined by readers, not writers.
- Delaying the documentation (commenting the code) often means it will never be written.
- "If you are not making [software] design better, you're probably making it worse".
- Don't change existing connections (unless you're changing everything) - keeping consistency is better than better style in some places but not all.
- TDD usually divides attention on specific features rather then design; when tests-first approach makes sense is fixing issues: you replicate it with failing test, then fix it.
- "Measure before modifying" - mostly about performance here, but a good principle on general for any changes or improvements.
- "It's a great feeling to discover a solution that is both simple and powerful. A clean, simple and obvious design is a beautiful thing"
It's a great book - clear, concise, very relevant and applicable, and of very palatable size. Great read for anyone related to a software systems design.