More on this book
Community
Kindle Notes & Highlights
The obvious appeal of architecture is structure, and structure is something that dominates the paradigms and discussions of software development—components, classes, functions, modules, layers, and services, micro or macro.
Software may be such stuff as dreams are made on, but it runs in the physical world.
Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change. —Grady Booch
How do we reduce future development effort and cost without crystal balls and time machines?
Architecture is the decisions that you wish you could get right early in a project, but that you are not necessarily more likely to get them right than any other. —Ralph Johnson
we operate with incomplete knowledge,
Architecture is a hypothesis, that needs to be proven by implementation and measurement. —Tom Gilb
To walk this path requires care and attention, thought and observation, practice and principle. This might at first sound slow, but it’s all in the way that you walk. The only way to go fast, is to go well. —Robert C. Martin
Enjoy the journey. —Kevlin...
This highlight has been truncated due to consecutive passage length restrictions.
The architecture rules are the same!
the rules of software architecture are independent of every other variable.
True—and yet the code is still just an assemblage of sequence, selection, and iteration, just as it was back in the 1960s and 1950s.
Getting software right is hard.
when you get software right, something magical happens: You don’t need hordes of programmers to keep it working. You don’t need massive requirements documents and huge issue tracking systems. You don’t need global cube farms and 24/7 programming.
When software is done right, it requires a fraction of the human resources to create and maintain. Changes are simple and rapid. Defects are few and far between. Effort is minimized, and functionality and flexibility are maximized.
The goal of software architecture is to minimize the human resources required to build and maintain the required system.
If that effort is low, and stays low throughout the lifetime of the system, the design is good. If that effort grows with each new release, the design is bad. It’s as simple as that.
Modern developers are in a similar race, and exhibit a similar overconfidence. Oh, they don’t sleep—far from it. Most modern developers work their butts off. But a part of their brain does sleep—the part that knows that good, clean, well-designed code matters.
The only way to go fast, is to go well.
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.
Their overconfidence will drive the redesign into the same mess as the original project.
Every software system provides two different values to the stakeholders: behavior and structure.
Therefore architectures should be as shape agnostic are practical.
Is it more important for the software system to work, or is it more important for the software system to be easy to change?
Effective software development teams tackle that struggle head on. They unabashedly squabble with all the other stakeholders as equals.
In 1938, Alan Turing laid the foundations of what was to become computer programming. He was not the first to conceive of a programmable machine, but he was the first to understand that programs were simply data. By 1945, Turing was writing real programs on real
structured programming, object-orient programming, and functional programming.
Object-oriented programming imposes discipline on indirect transfer of control.
The three paradigms together remove goto statements, function pointers, and assignment. Is there anything left to take away? Probably not.
Notice how well those three align with the three big concerns of architecture: function, separation of components, and data management.
Dijkstra concluded that the intellectual challenge of programming was greater than the intellectual challenge of theoretical physics.
mathematical proofs are not the only strategy for proving something correct. Another highly successful strategy is the scientific method.
Science is fundamentally different from mathematics, in that scientific theories and laws cannot be proven correct.
That is the nature of scientific theories and laws: They are falsifiable but not provable.
Science does not work by proving statements true, but rather by proving statements false.
mathematics is the discipline of proving provable statements true. Science, in contrast, is the discipline of proving provable statements false.
Dijkstra once said, “Testing shows the presence, not the absence, of bugs.”
Rather, software is like a science. We show correctness by failing to prove incorrectness, despite our best efforts.
Software architects strive to define modules, components, and services that are easily falsifiable (testable).
Java and C# simply abolished the header/implementation split altogether, thereby weakening encapsulation even more. In these languages, it is impossible to separate the declaration and definition of a class.
pointers to functions are dangerous.
OO allows the plugin architecture to be used anywhere, for anything.
software architects working in systems written in OO languages have absolute control over the direction of all source code dependencies in the system. They are not constrained to align those dependencies with the flow of control. No matter which module does the calling and which module is called, the software architect can point the source code dependency in either direction.
What can you do with that power? As an example, you can rearrange the source code dependencies of your system so that the database and the user interface (UI) depend on the business rules (Figure 5.3), rather than the other way around. Figure 5.3 The database and the user interface depend on the business rules This means that the UI and the database can be plugins to the business rules. It means that the source code of the business rules never mentions the UI or the database.
the business rules, the UI, and the database can be compiled into three separate components or deployment units (e.g., jar files, DLLs, or Gem files)
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.
The point is that well-structured applications will be segregated into those components that do not mutate variables and those that do.
Architects would be wise to push as much processing as possible into the immutable components, and to drive as much code as possible out of those components that must allow mutation.