Clean Architecture: A Craftsman's Guide to Software Structure and Design
Rate it:
Open Preview
16%
Flag icon
The more memory we have, and the faster our machines are, the less we need mutable state.
16%
Flag icon
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.
16%
Flag icon
If we have enough storage and enough processor power, we can make our applications entirely immutable—and, therefore, entirely functional.
16%
Flag icon
If this still sounds absurd, it might help if you remembered that this is precisely the way your source code control system works.
16%
Flag icon
Structured programming is discipline imposed upon direct transfer of control.
16%
Flag icon
Object-oriented programming is discipline imposed upon indirect transfer of control.
16%
Flag icon
Functional programming is discipline imposed upon variable assignment.
17%
Flag icon
Each of these three paradigms has taken something away from us. Each restricts some aspect of the way we write code. None of them has added to our power or our capabilities.
17%
Flag icon
What we have learned over the last half-century i...
This highlight has been truncated due to consecutive passage length restrictions.
17%
Flag icon
With that realization, we have to face an unwelcome fact: Software is not a rapid...
This highlight has been truncated due to consecutive passage length restrictions.
17%
Flag icon
The rules of software are the same today as they were in 1946, when Alan Turing wrote the very first code that would ...
This highlight has been truncated due to consecutive passage length restrictions.
17%
Flag icon
The tools have changed, and the hardware has changed, but the essence of sof...
This highlight has been truncated due to consecutive passage length restrictions.
17%
Flag icon
the stuff of computer programs—is composed of sequence, selection, iteration, and indirection....
This highlight has been truncated due to consecutive passage length restrictions.
17%
Flag icon
Good software systems begin with clean code. On the one hand, if the bricks aren’t well made, the architecture of the building doesn’t matter much.
17%
Flag icon
On the other hand, you can make a substantial mess with well-made bricks. This is where the SOLID principles come in.
17%
Flag icon
SRP: The Single Responsibility Principle
17%
Flag icon
OCP: The Open-Closed Principle
17%
Flag icon
they must be designed to allow the behavior of those systems to be changed by adding new code, rather than changing existing
17%
Flag icon
LSP: The Liskov Substitution Principle
17%
Flag icon
In short, this principle says that to build software systems from interchangeable parts, those parts must adhere to a contract that allows those parts to be substituted one for another.
17%
Flag icon
The Interface Segregation Principle This principle advises software designers to avoid depending on things that they don’t use.
17%
Flag icon
The Dependency Inversion Principle The code that implements high-level policy should not depend on the code that implements low-level details. Rather, details should depend on policies.
18%
Flag icon
Historically, the SRP has been described this way: A module should have one, and only one, reason to change.
18%
Flag icon
A module should be responsible to one, and only one, actor.
18%
Flag icon
SYMPTOM 1: ACCIDENTAL DUPLICATION
18%
Flag icon
The SRP says to separate the code that different actors depend
18%
Flag icon
SYMPTOM 2: MERGES
18%
Flag icon
Once again, the way to avoid this problem is to separate code that supports different actors.
19%
Flag icon
The EmployeeFacade contains very little code. It is responsible for instantiating and delegating to the classes with the functions.
19%
Flag icon
business rules closer to the data. This can be done by keeping the most important method in the original Employee class and then using that class as a Facade for the lesser functions
19%
Flag icon
A software artifact should be open for extension but closed for modification.
20%
Flag icon
Interactors are the highest-level concept, so they are the most protected. Views are among the lowest-level concepts, so they are the least protected. Presenters are higher level than Views, but lower level than the Controller or the Interactor.
20%
Flag icon
This is how the OCP works at the architectural level. Architects separate functionality based on how, why, and when it changes, and then organize that separated functionality into a hierarchy of components.
20%
Flag icon
Transitive dependencies are a violation of the general principle that software entities should not depend on things they don’t directly use.
20%
Flag icon
even though our first priority is to protect the Interactor from changes to the Controller, we also want to protect the Controller from changes to the Interactor by hiding the internals of the Interactor.
20%
Flag icon
The OCP is one of the driving forces behind the architecture of systems. The goal is to make the system easy to extend without incurring a high impact of change.
20%
Flag icon
What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.
21%
Flag icon
Since the behavior of the User depends on the types it uses, those types are not substitutable.
21%
Flag icon
The LSP can, and should, be extended to the level of architecture. A simple violation of substitutability, can cause a system’s architecture to be polluted with a significant amount of extra mechanisms.
21%
Flag icon
Let’s assume that User1 uses only op1, User2 uses only op2, and User3 uses only op3.
21%
Flag icon
Now imagine that OPS is a class written in a language like Java. Clearly, in that case, the source code of User1 will inadvertently depend on op2 and op3, even though it doesn’t call them.
22%
Flag icon
This problem can be resolved by segregating the operations into interfaces as shown in Figure 10.2.
22%
Flag icon
In general, it is harmful to depend on modules that contain more than you need. This is obviously true for source code dependencies that can force unnecessary recompilation and redeployment—but it is also true at a much higher, architectural level.
22%
Flag icon
The lesson here is that depending on something that carries baggage that you don’t need can cause you troubles that you didn’t expect. We’ll explore this idea in more detail when we discuss the Common Reuse Principle in Chapter 13, “Component Cohesion.”
22%
Flag icon
The Dependency Inversion Principle (DIP) tells us that the most flexible systems are those in which source code dependencies refer only to abstractions, not to concretions.
22%
Flag icon
In a statically typed language, like Java, this means that the use, import, and include statements should refer only to source modules containing interfaces, abstract classes, or some other kind of abstract declaration. Nothing concrete should be depended on.
22%
Flag icon
The same rule applies for dynamically typed languages, like Ruby and Python. Source code dependencies should not refer to concrete modules. However, in these languages it is a bit harder to define what a concrete module is. In particular, it i...
This highlight has been truncated due to consecutive passage length restrictions.
22%
Flag icon
It is the volatile concrete elements of our system that we want to avoid depending on. Those are the modules that we are actively developing, and that are undergoing frequent change.
22%
Flag icon
Therefore interfaces are less volatile than implementations.
22%
Flag icon
Indeed, good software designers and architects work hard to reduce the volatility of interfaces.