Clean Architecture: A Craftsman's Guide to Software Structure and Design
Rate it:
Open Preview
Kindle Notes & Highlights
16%
Flag icon
More importantly, nothing ever gets deleted or updated from such a data store. As a consequence, our applications are not CRUD; they are just CR. Also, because neither updates nor deletions occur in the data store, there cannot be any concurrent update issues.
16%
Flag icon
What we have learned over the last half-century is what not to do. With that realization, we have to face an unwelcome fact: Software is not a rapidly advancing technology.
16%
Flag icon
Software—the stuff of computer programs—is composed of sequence, selection, iteration, and indirection. Nothing more. Nothing less.
18%
Flag icon
A module should be responsible to one, and only one, actor.
18%
Flag icon
Cohesion is the force that binds together the code responsible to a single actor.
18%
Flag icon
SYMPTOM 1: ACCIDENTAL DUPLICATION
18%
Flag icon
These problems occur because we put code that different actors depend on into close proximity. The SRP says to separate the code that different actors depend on.
18%
Flag icon
The three classes share access to EmployeeData, which is a simple data structure with no methods (Figure 7.3). Each class holds only the source code necessary for its particular function. The three classes are not allowed to know about each other. Thus any accidental duplication is avoided.
19%
Flag icon
Each of the classes that contain such a family of methods is a scope. Outside of that scope, no one knows that the private members of the family exist.
19%
Flag icon
A software artifact should be open for extension but closed for modification.
19%
Flag icon
Classes marked with <I> are interfaces; those marked with <DS> are data structures. Open arrowheads are using relationships. Closed arrowheads are implements or inheritance relationships.
19%
Flag icon
Let me say that again: If component A should be protected from changes in component B, then component B should depend on component A.
19%
Flag icon
Why should the Interactor hold such a privileged position? Because it contains the business rules. The Interactor contains the highest-level policies of the application.
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. Higher-level components in that hierarchy are protected from the changes made to lower-level components.
20%
Flag icon
It is there to protect the FinancialReportController from knowing too much about the internals of the Interactor.
20%
Flag icon
we also want to protect the Controller from changes to the Interactor by hiding the internals of the Interactor.
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
20%
Flag icon
Or we might have a set of services that all respond to the same REST interface.
20%
Flag icon
In all of these situations, and more, the LSP is applicable because there are users who depend on well-defined interfaces, and on the substitutability of the implementations of those interfaces.
22%
Flag icon
In dynamically typed languages like Ruby and Python, such declarations don’t exist in source code. Instead, they are inferred at runtime. Thus there are no source code dependencies to force recompilation and redeployment. This is the primary reason that dynamically typed languages create systems that are more flexible and less tightly coupled than statically typed languages.
22%
Flag icon
Even worse, a failure of one of the features within D may cause failures in F and S.
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
By comparison, the String class is very stable.
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
Indeed, good software designers and architects work hard to reduce the volatility of interfaces. They try to find ways to add functionality to implementations without making changes to the interfaces. This is Software Design 101.
22%
Flag icon
It also puts severe constraints on the creation of objects and generally enforces the use of Abstract Factories.
22%
Flag icon
Don’t derive from volatile concrete classes.
23%
Flag icon
Note that the flow of control crosses the curved line in the opposite direction of the source code dependencies. The source code dependencies are inverted against the flow of control—which is why we refer to this principle as Dependency Inversion.
23%
Flag icon
Most systems will contain at least one such concrete component—often called main because it contains the main1 function. In the case illustrated in Figure 11.1, the main function would instantiate the ServiceFactoryImpl and place that instance in a global variable of type ServiceFactory. The Application would then access the factory through that global variable.
23%
Flag icon
If the SOLID principles tell us how to arrange the bricks into walls and rooms, then the component principles tell us how to arrange the rooms into buildings. Large software systems, like large buildings, are built out of smaller components.
23%
Flag icon
Components are the units of deployment. They are the smallest entities that can be deployed as part of a system.
25%
Flag icon
Which classes belong in which components? This is an important decision, and requires guidance from good software engineering principles.
25%
Flag icon
• REP: The Reuse/Release Equivalence Principle • CCP: The Common Closure Principle • CRP: The Common Reuse Principle
25%
Flag icon
The granule of reuse is the granule of release.
25%
Flag icon
The Reuse/Release Equivalence Principle (REP) is a principle that seems obvious, at least in hindsight. People who want to reuse software components cannot, and will not, do so unless those components are tracked through a release process and are given release numbers.
25%
Flag icon
Therefore the release process must produce the appropriate notifications and release documentation so that users can make informed decisions about when and whether to integrate the new release.
25%
Flag icon
From a software design and architecture point of view, this principle means that the classes and modules that are formed into a component must belong to a cohesive group.
25%
Flag icon
instead, there must be some overarching theme or purpose that tho...
This highlight has been truncated due to consecutive passage length restrictions.
25%
Flag icon
Classes and modules that are grouped together into a component should be releasable together.
25%
Flag icon
Gather into components those classes that change for the same reasons and at the same times. Separate into different components those classes that change at different times and for different reasons.
25%
Flag icon
For most applications, maintainability is more important than reusability.
26%
Flag icon
As stated earlier, the CCP is the component form of the SRP.
26%
Flag icon
Gather together those things that change at the same times and for the same reasons. Separate those things that change at different times or for different reasons.
26%
Flag icon
THE COMMON REUSE PRINCIPLE Don’t force users of a component to depend on things they don’t need.
26%
Flag icon
Put another way, we want to make sure that the classes that we put into a component are inseparable—that it is impossible to depend on some and not on the others.
26%
Flag icon
The CRP says that classes that are not tightly bound to each other should not be in the same component.
26%
Flag icon
The CRP is the generic version of the ISP. The ISP advises us not to depend on classes that have methods we don’t use. The CRP advises us not to depend on components that have classes we don’t use.
26%
Flag icon
Don’t depend on things you don’t need.
26%
Flag icon
A good architect finds a position in that tension triangle that meets the current concerns of the development team, but is also aware that those concerns will change over time.
26%
Flag icon
As a consequence, the composition of the components will likely jitter and evolve with time as the focus of the project changes from develop-ability to reusability.