Clean Architecture: A Craftsman's Guide to Software Structure and Design
Rate it:
Open Preview
Kindle Notes & Highlights
3%
Flag icon
It is a choice founded on a further set of choices: what to include; what to exclude; what to emphasize by shape or color; what to de-emphasize through uniformity or omission.
3%
Flag icon
There is nothing natural or intrinsic about one view over another.
4%
Flag icon
This is the monstrosity in love, lady, that the will is infinite, and the execution confined; that the desire is boundless, and the act a slave to limit.
4%
Flag icon
Not only does a good architecture meet the needs of its users, developers, and owners at a given point in time, but it also meets them over time.
4%
Flag icon
If you think good architecture is expensive, try bad architecture.
4%
Flag icon
The kinds of changes a system’s development typically experiences should not be the changes that are costly, that are hard to make, that take managed projects of their own rather than being folded into the daily and weekly flow of work.
4%
Flag icon
How do we know what those typical changes will be so that we can shape those significant decisions around them? How do we reduce future development effort and cost without crystal balls and time machines?
4%
Flag icon
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.
4%
Flag icon
The path we are most interested is the cleanest one. It recognizes the softness of software and aims to preserve it as a first-class property of the system.
4%
Flag icon
A good architecture comes from understanding it more as a journey than as a destination, more as an ongoing process of enquiry than as a frozen artifact.
4%
Flag icon
The only way to go fast, is to go well.
4%
Flag icon
Why should such different systems all share similar rules of architecture? My conclusion is that the rules of software architecture are independent of every other variable.
5%
Flag icon
That’s the secret: This changelessness of the code is the reason that the rules of software architecture are so consistent across system types. The rules of software architecture are the rules of ordering and assembling the building blocks of programs. And since those building blocks are universal and haven’t changed, the rules for ordering them are likewise universal and changeless.
5%
Flag icon
Hoards of junior programmers in cube farms around the world slog through massive requirements documents held in huge issue tracking systems to get their systems to “work” by the sheer brute force of will.
5%
Flag icon
Getting it right is another matter entirely. Getting software right is hard. It takes knowledge and skills that most young programmers haven’t yet acquired. It requires thought and insight that most programmers don’t take the time to develop. It requires a level of discipline and dedication that most programmers never dreamed they’d need. Mostly, it takes a passion for the craft and the desire to be a professional.
5%
Flag icon
And 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.
6%
Flag icon
Have you been to programming hell?
6%
Flag icon
The goal of software architecture is to minimize the human resources required to build and maintain the required system.
6%
Flag icon
The measure of design quality is simply the measure of the effort required to meet the needs of the customer. 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.
7%
Flag icon
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.
7%
Flag icon
The fact is that making messes is always slower than staying clean, no matter which time scale you are using.
7%
Flag icon
The only way to go fast, is to go well.
7%
Flag icon
In every case, the best option is for the development organization to recognize and avoid its own overconfidence and to start taking the quality of its software architecture seriously.
8%
Flag icon
Every software system provides two different values to the stakeholders: behavior and structure. Software developers are responsible for ensuring that both those values remain high.
8%
Flag icon
To fulfill its purpose, software must be soft—that is, it must be easy to change. When the stakeholders change their minds about a feature, that change should be simple and easy to make. The difficulty in making such a change should be proportional only to the scope of the change, and not to the shape of the change.
8%
Flag icon
It is this difference between scope and shape that often drives the growth in software development costs. It is the reason that costs grow out of proportion to the size of the requested changes. It is the reason that the first year of development is much cheaper than the second, and the second year is much cheaper than the third.
8%
Flag icon
I have two kinds of problems, the urgent and the important. The urgent are not important, and the important are never urgent.
9%
Flag icon
That’s what software developers were hired to do. Therefore it is the responsibility of the software development team to assert the importance of architecture over the urgency of features.
9%
Flag icon
The development team has to struggle for what they believe to be best for the company, and so do the management team, and the marketing team, and the sales team, and the operations team. It’s always a struggle.
9%
Flag icon
Just remember: If architecture comes last, then the system will become ever more costly to develop, and eventually change will become practically impossible for part or all of the system. If that is allowed to happen, it means the software development team did not fight hard enough for what they knew was necessary.
9%
Flag icon
Structured programming imposes discipline on direct transfer of control.
9%
Flag icon
These two programmers noticed that the function call stack frame in the ALGOL language could be moved to a heap, thereby allowing local variables declared by a function to exist long after the function returned. The function became a constructor for a class, the local variables became instance variables, and the nested functions became methods. This led inevitably to the discovery of polymorphism through the disciplined use of function pointers.
9%
Flag icon
Object-oriented programming imposes discipline on indirect transfer of control.
9%
Flag icon
Functional programming imposes discipline upon assignment.
10%
Flag icon
Notice how well those three align with the three big concerns of architecture: function, separation of components, and data management.
10%
Flag icon
The problem that Dijkstra recognized, early on, was that programming is hard, and that programmers don’t do it very well.
10%
Flag icon
Other uses of goto, however, did not have this problem. Dijkstra realized that these “good” uses of goto corresponded to simple selection and iteration control structures such as if/then/else and do/while. Modules that used only those kinds of control structures could be recursively subdivided into provable units.
10%
Flag icon
They had been identified two years before by Böhm and Jacopini, who proved that all programs can be constructed from just three structures: sequence, selection, and iteration.
11%
Flag icon
TESTS Dijkstra once said, “Testing shows the presence, not the absence, of bugs.” In other words, a program can be proven incorrect by a test, but it cannot be proven correct. All that tests can do, after sufficient testing effort, is allow us to deem a program to be correct enough for our purposes.
12%
Flag icon
Even so, the languages that claim to provide OO have only weakened the once perfect encapsulation we enjoyed with C.
13%
Flag icon
The UNIX operating system requires that every IO device driver provide five standard functions:5 open, close, read, write, and seek. The signatures of those functions must be identical for every IO driver.
13%
Flag icon
The bottom line is that polymorphism is an application of pointers to functions. Programmers have been using pointers to functions to achieve polymorphic behavior since Von Neumann architectures were first implemented in the late 1940s. In other words, OO has provided nothing new. Ah, but that’s not quite correct. OO languages may not have given us polymorphism, but they have made it much safer and much more convenient.
14%
Flag icon
OO languages eliminate these conventions and, therefore, these dangers. Using an OO language makes polymorphism trivial. That fact provides an enormous power that old C programmers could only dream of. On this basis, we can conclude that OO imposes discipline on indirect transfer of control.
14%
Flag icon
Note, however, that the source code dependency (the inheritance relationship) between ML1 and the interface I points in the opposite direction compared to the flow of control. This is called dependency inversion, and its implications for the software architect are profound.
14%
Flag icon
That is power! That is the power that OO provides. That’s what OO is really all about—at least from the architect’s point of view.
14%
Flag icon
In short, 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.
15%
Flag icon
OO is the ability, through the use of polymorphism, to gain absolute control over every source code dependency in the system. It allows the architect to create a plugin architecture, in which modules that contain high-level policies are independent of modules that contain low-level details. The low-level details are relegated to plugin modules that can be deployed and developed independently from the modules that contain high-level policies.
15%
Flag icon
This leads us to a surprising statement: Variables in functional languages do not vary.
15%
Flag icon
In other words, all the problems that we face in concurrent applications—all the problems we face in applications that require multiple threads, and multiple processors—cannot happen if there are no mutable variables. As an architect, you should be very interested in issues of concurrency. You want to make sure that the systems you design will be robust in the presence of multiple threads and processors. The question you must be asking yourself, then, is whether immutability is practicable.
16%
Flag icon
This is the idea behind event sourcing.2 Event sourcing is a strategy wherein we store the transactions, but not the state. When state is required, we simply apply all the transactions from the beginning of time.
« Prev 1 3 6