This is my summary and notes from A Philosophy of Software Design, 2nd Edition by John Ousterhout. Please use the link if you decide to buy the book after reading this as it contains my affiliate code. Thanks.
The most fundamental problem in computer science is problem decomposition: how to take a complex problem and divide it up into pieces that can be solved independently.
modular design), so that programmers can work on a system without being exposed to all of its complexity at once.
C) is determined by the complexity of each part p (
cₚ) weighted by the fraction of time developers spend working on that part (
If the API for a commonly used feature forces users to learn about other features that are rarely used, this increases the cognitive load on users who don’t need the rarely used features.
Sometimes an approach that requires more lines of code is actually simpler, because it reduces cognitive load.
10–20%of total development time on investments. This amount is small enough that it won’t impact your schedules significantly, but large enough to produce significant benefits over time.
Nlines should be divided into multiple methods
Classitis may result in classes that are individually simple, but it increases the complexity of the overall system. Small classes don’t contribute much functionality, so there have to be a lot of them, each with its own interface. These interfaces accumulate to create tremendous complexity at the system level. Small classes also result in a verbose programming style, due to the boilerplate required for each class.
Each piece of design infrastructure added to a system, such as an interface, argument, function, class, or definition, adds complexity, since developers must learn about this element. In order for an element to provide a net gain against complexity, it must eliminate some complexity that would be present in the absence of the design element. Otherwise, you are better off implementing the system without that particular element. For example, a class can reduce complexity by encapsulating functionality so that users of the class needn’t be aware of it.
- Software systems are composed in layers, where higher layers use the facilities provided by lower layers and each layer has a different abstraction (level).
This is an instance of a general red flag: if two pieces of code are physically separated, but each can only be understood by looking at the other.
“Every computer program is a model, hatched in the mind, of a real or mental process. These processes, arising from human experience and thought, are huge in number, intricate in detail, and at any time only partially understood. They are modeled to our permanent satisfaction rarely by our computer programs. Thus even though our programs are carefully handcrafted discrete collections of symbols, mosaics of interlocking functions, they continually evolve: we change them as our perception of the model deepens, enlarges, generalizes until the model ultimately attains a metastable place within still another model with which we struggle”
Comments are fundamental to abstractions: an abstraction is a simplified view of an entity, which preserves essential information but omits details that can safely be ignored. If users must read the code of a method in order to use it, then there is no abstraction: all of the complexity of the method is exposed.
Some of the things the author said should be in comments can instead be in code:
(startInclusive, endExclusive)instead of
(start, end)— the former doesn’t need extra documentation, the later does.
“If your code is undergoing review and a reviewer tells you that something is not obvious, don’t argue with them; if a reader thinks it’s not obvious, then it’s not obvious”
While this is usually true, it’s not always true. Also, “obvious” is subjective — you can make your code obvious for one person, and it becomes obscure to another.
Keep in mind people then to use unrelated words to describe a phenomenon. E.g: Conflating unfamiliarity with complexity.
“The greater the distance between a name’s declaration and its uses, the longer the name should be.” — Andrew Gerrand
1private List<Message> incomingMessageList;2...3incomingMessageList = new ArrayList<Message>();