Clean Architecture: A Craftsman's Guide to Software Structure and Design
Rate it:
Open Preview
Kindle Notes & Highlights
27%
Flag icon
The forces that impinge upon the architecture of a component structure are technical, political, and volatile.
27%
Flag icon
Notice one more thing: Regardless of which component you begin at, it is impossible to follow the dependency relationships and wind up back at that component. This structure has no cycles. It is a directed acyclic graph (DAG).
28%
Flag icon
In fact, component dependency diagrams have very little do to with describing the function of the application. Instead, they are a map to the buildability and maintainability of the application. This is why they aren’t designed at the beginning of the project.
28%
Flag icon
THE STABLE DEPENDENCIES PRINCIPLE Depend in the direction of stability.
28%
Flag icon
By conforming to the Common Closure Principle (CCP), we create components that are sensitive to certain kinds of changes but immune to others. Some of these components are designed to be volatile. We expect them to change.
29%
Flag icon
Webster’s Dictionary says that something is stable if it is “not easily moved.” Stability is related to the amount of work required to make a change. On the one hand, the standing penny is not stable because it requires very little work to topple it. On the other hand, a table is very stable because it takes a considerable amount of effort to turn it over.
29%
Flag icon
One sure way to make a software component difficult to change, is to make lots of other software components depend on it.
30%
Flag icon
A component should be as abstract as it is stable.
30%
Flag icon
The Stable Abstractions Principle (SAP) sets up a relationship between stability and abstractness.
30%
Flag icon
The SAP and the SDP combined amount to the DIP for components. This is true because the SDP says that dependencies should run in the direction of stability, and the SAP says that stability implies abstraction. Thus dependencies run in the direction of abstraction.
30%
Flag icon
The combination of the SDP and the SAP deals with components, and allows that a component can be partially abstract and partially stable.
30%
Flag icon
Not all components fall into one of these two positions, because components often have degrees of abstraction and stability.
31%
Flag icon
Consider a component in the area of (0, 0). This is a highly stable and concrete component.
31%
Flag icon
Some software entities do, in fact, fall within the Zone of Pain. An example would be a database schema. Database schemas are notoriously volatile, extremely concrete, and highly depended on. This is one reason why the interface between OO applications and databases is so difficult to manage, and why schema updates are generally painful.
31%
Flag icon
Given this metric, a design can be analyzed for its overall conformance to the Main Sequence. The D metric for each component can be calculated. Any component that has a D value that is not near zero can be reexamined and restructured.
31%
Flag icon
This pattern reflects that experience. However, a metric is not a god; it is merely a measurement against an arbitrary standard. These metrics are imperfect, at best, but it is my hope that you find them useful.
32%
Flag icon
Software architects are the best programmers, and they continue to take programming tasks, while they also guide the rest of the team toward a design that maximizes productivity.
32%
Flag icon
The form of that shape is in the division of that system into components, the arrangement of those components, and the ways in which those components communicate with each other.
32%
Flag icon
The purpose of that shape is to facilitate the development, deployment, operation, and maintenance of the software system contained within it.
32%
Flag icon
The strategy behind that facilitation is to leave as many options open as possible,...
This highlight has been truncated due to consecutive passage length restrictions.
32%
Flag icon
The primary purpose of architecture is to support the life cycle of the system. Good architecture makes the system easy to understand, easy to develop, easy to maintain, and easy to deploy.
32%
Flag icon
A goal of a software architecture, then, should be to make a system that can be easily deployed with a single action.
32%
Flag icon
Had the architects considered deployment issues early on, they might have decided on fewer services, a hybrid of services and in-process components, and a more integrated means of managing the interconnections.
32%
Flag icon
The fact that hardware is cheap and people are expensive means that architectures that impede operation are not as costly as architectures that impede development, deployment, and maintenance.
32%
Flag icon
A good software architecture communicates the operational needs of the system.
33%
Flag icon
Of all the aspects of a software system, maintenance is the most costly. The never-ending parade of new features and the inevitable trail of defects and corrections consume vast amounts of human resources.
33%
Flag icon
Spelunking is the cost of digging through the existing software, trying to determine the best place and the best strategy to add a new feature or to repair a defect.
33%
Flag icon
As we described in an earlier chapter, software has two types of value: the value of its behavior and the value of its structure. The second of these is the greater of the two because it is this value that makes software soft.
33%
Flag icon
The way you keep software soft is to leave as many options open as possible, for as long as possible. What are the options that we need to leave open? They are the details that don’t matter.
33%
Flag icon
All software systems can be decomposed into two major elements: policy and details.
33%
Flag icon
The details are those things that are necessary to enable humans, other systems, and programmers to communicate with the policy, but that do not impact the behavior of the policy at all. They include IO devices, databases, web systems, servers, frameworks, communication protocols, and so forth.
33%
Flag icon
This allows decisions about those details to be delayed and deferred.
33%
Flag icon
if the architect is careful, the high-level policy will not care if the database is relational, distributed, hierarchical, or just plain flat files.
33%
Flag icon
It is not necessary to adopt REST early in development, because the high-level policy should be agnostic about the interface to the outside world. Nor is it necessary to adopt a micro-services framework, or a SOA framework. Again, the high-level policy should not care about these things.
33%
Flag icon
And the longer you wait to make those decisions, the more information you have with which to make them properly.
33%
Flag icon
A good architect maximizes the number of decisions not made.
35%
Flag icon
Good architects carefully separate details from policy, and then decouple the policy from the details so thoroughly that the policy has no knowledge of the details and does not depend on the details in any way.
35%
Flag icon
The most important thing a good architecture can do to support behavior is to clarify and expose that behavior so that the intent of the system is visible at the architectural level.
35%
Flag icon
Those elements will be classes or functions or modules that have prominent positions within the architecture, and they will have names that clearly describe their function.
35%
Flag icon
As strange as it may seem, this decision is one of the options that a good architect leaves open.
35%
Flag icon
monolithic structure, cannot easily be upgraded
35%
Flag icon
A system that must be developed by an organization with many teams and many concerns must have an architecture that facilitates independent actions by those teams, so that the teams do not interfere with each other during development. This is accomplished by properly partitioning the system into well-isolated, independently developable components.
35%
Flag icon
A good architecture makes the system easy to change, in all the ways that it must change, by leaving options open.
35%
Flag icon
So the architect can employ the Single Responsibility Principle and the Common Closure Principle to separate those things that change for different reasons, and to collect those things that change for the same reasons—given the context of the intent of the system.
36%
Flag icon
The database, the query language, and even the schema are technical details that have nothing to do with the business rules or the UI. They will change at rates, and for reasons, that are independent of other aspects of the system. Consequently, the architecture should separate them from the rest of the system so that they can be independently changed.
36%
Flag icon
To achieve this decoupling, we separate the UI of the add-order use case from the UI of the delete-order use case. We do the same with the business rules, and with the database. We keep the use cases separate down the vertical height of the system.
36%
Flag icon
Remember, a good architecture leaves options open. The decoupling mode is one of those options.
36%
Flag icon
The decoupling of the use cases and layers also affords a high degree of flexibility in deployment. Indeed, if the decoupling is done well, then it should be possible to hot-swap layers and use cases in running systems. Adding a new use case could be as simple as adding a few new jar files or services to the system while leaving the rest alone.
36%
Flag icon
Most likely it is accidental. As time goes by, the odds are that those two screens will diverge and eventually look very different. For this reason, care must be taken to avoid unifying them. Otherwise, separating them later will be a challenge.
37%
Flag icon
Creating the separate view model is not a lot of effort, and it will help you keep the layers properly decoupled.