- The Goal: The goal of software architecture is to minimize the human resources required to build and maintain the required system. (p. 5)
- Dev Responsibility: The only way to reverse the decline in productivity and the increase in cost is to get the developers to stop thinking like the overconfident Hare and start taking responsibility for the mess that they’ve made. (p. 12)
- Values
- Behavior
- Programmers are hired to make machines behave in a way that makes or saves money for the stakeholders. (p. 14)
- Urgent but not always particularly important
- Architecture
- Architectures should be as shape agnostic as practical. (p. 15)
- Important but never particularly urgent
- Behavior
- Structured Programming - Imposes discipline on direct transfer of control (i.e., makes it difficult to do unrestrained jumps like
goto
statements; replace withif
/then
and other control constructs) - Object-Oriented Programming - Imposes discipline on indirect transfer of control (i.e., ???; function retains structure and variables after it finishes)
- Functional Programming - Imposes discipline upon assignment (i.e., immutability)
Each of the paradigms removes capabilities from the programmer. None of them adds new capabilities. Each imposes some kind of extra discipline that is negative in its intent. The paradigms tell us what not to do, more than they tell us what to do.
We use polymorphism as the mechanism to cross architectural boundaries; we use functional programming to impose discipline on the location of and access to data; and we use structured programming as the algorithmic foundation of our modules. Notice how well those three align with the three big concerns of architecture: function, separation of components, and data management.
All programs can be constructed from just three structures: sequence, selection, and iteration.
Science does not work by proving statements true, but rather by proving statements false.
Structured programming allows modules to be recursively decomposed into provable units, which in turn means that modules can be functionally decomposed. That is, you can take a large-scale problem statement and decompose it into high-level functions. Each of those functions can then be decomposed into lower-level functions, ad infinitum. Moreover, each of those decomposed functions can be represented using the restricted control structures of structured programming.
- What is OO programming?
- Encapsulation?
- Was already in C and weakened in C++.
- "The way encapsulation is partially repaired is by introducing the public, private, and protected keywords into the language."
- Inheritance?
- Again, already in C, but OO made it more convenient.
- Polymorphism?
- "polymorphism is an application of pointers to functions."
- OO made it safer and much more convenient
- Encapsulation?
The fact that OO languages provide safe and convenient polymorphism means that any source code dependency, no matter where it is, can be inverted.
- OO allows the software architect to point dependencies in either direction. 🤔 I don't know what this means yet
- when the source code in a component changes, only that component needs to be redeployed. This is independent deployability.
- If the modules in your system can be deployed independently, then they can be developed independently by different teams. That’s independent developability.
- Variables in functional languages do not vary.
- All race conditions, deadlock conditions, and concurrent update problems are due to mutable variables. You cannot have a race condition or a concurrent update problem if no variable is ever updated. You cannot have deadlocks without mutable locks.