Clean Architecture: A Craftsman's Guide to Software Structure and Design
Rate it:
Open Preview
29%
Flag icon
Finally, as cycles appear, the ADP is applied and the component dependency graph jitters and grows.
29%
Flag icon
THE STABLE DEPENDENCIES PRINCIPLE
29%
Flag icon
Depend in the direction of stability.
29%
Flag icon
Any component that we expect to be volatile should not be depended on by a component that is difficult to change. Otherwise, the volatile component will also be difficult to change.
29%
Flag icon
By conforming to the Stable Dependencies Principle (SDP), we ensure that modules that are intended to be easy to change are not depended on by modules that are harder to change.
29%
Flag icon
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
29%
Flag icon
On the other hand, a table is very stable because it takes a considerable amount of effort to turn it over.
30%
Flag icon
Putting the unstable components at the top of the diagram is a useful convention because any arrow that points up is violating the SDP (and, as we shall see later, the ADP).
30%
Flag icon
A component should be as abstract as it is stable.
30%
Flag icon
classes that are flexible enough to be extended without requiring modification. Which kind of classes conform to this principle? Abstract classes.
30%
Flag icon
INTRODUCING THE STABLE ABSTRACTIONS PRINCIPLE The Stable Abstractions Principle (SAP) sets up a relationship between stability and abstractness.
30%
Flag icon
On the one hand, it says that a stable component should also be abstract so that its stability does not pre...
This highlight has been truncated due to consecutive passage length restrictions.
30%
Flag icon
the other hand, it says that an unstable component should be concrete since it its instability allows the concrete co...
This highlight has been truncated due to consecutive passage length restrictions.
30%
Flag icon
Thus, if a component is to be stable, it should consist of interfaces and abstract classes ...
This highlight has been truncated due to consecutive passage length restrictions.
30%
Flag icon
Thus dependencies run in the direction of abstraction.
30%
Flag icon
The A metric is a measure of the abstractness of a component. Its value is simply the ratio of interfaces and abstract classes in a component to the total number of classes in the component. • Nc: The number of classes in the component. • Na: The number of abstract classes and interfaces in the component. • A: Abstractness. A = Na ÷ Nc.
31%
Flag icon
is very common for one abstract class to derive from another abstract class.
31%
Flag icon
Some software entities do, in fact, fall within the Zone of Pain. An example would be a database schema.
31%
Flag icon
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
Another example of software that sits near the area of (0, 0) is a con...
This highlight has been truncated due to consecutive passage length restrictions.
31%
Flag icon
Thus this area is called the Zone of Uselessness. The software entities that inhabit this region are a kind of detritus. They are often leftover abstract classes that no one ever implemented. We find them in systems
31%
Flag icon
The locus of points that are maximally distant from each zone is the line that connects (1, 0) and (0, 1). I call this line the Main Sequence.
31%
Flag icon
A component that sits on the Main Sequence is not “too abstract” for its stability, nor is it “too unstable” for its abstractness.
31%
Flag icon
is neither useless nor particularly painful. It is depended on to the extent that it is abstract, and it depends on others to the extent that it is concrete.
31%
Flag icon
Good architects strive to position the majority of their components at those endpoints. However, in my experience, some small fraction of the components in a large system are neither perfectly abstract nor perfectly stable.
31%
Flag icon
create a metric that measures how far away a component is from this ideal.
31%
Flag icon
D3: Distance. D = |A+I–1| . The range of this metric is [0, 1]. A value of 0 indicates that the component is directly on the Main Sequence. A value of 1 indicates that the component is as far away as possible from the Main Sequence.
32%
Flag icon
Another way to use the metrics is to plot the D metric of each component over time.
32%
Flag icon
The dependency management metrics described in this chapter measure the conformance of a design to a pattern of dependency and abstraction that I think is a “good” pattern.
32%
Flag icon
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
First of all, a software architect is a programmer; and continues to be a programmer. Never fall for the lie that suggests that software architects pull back from code to focus on higher-level issues. They do not!
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. Software architects may not write as much code as other programmers do, but they continue to engage in programming tasks.
32%
Flag icon
The architecture of a software system is the shape given to that system by those who build it. 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
There are many systems out there, with terrible architectures, that work just fine. Their troubles do not lie in their operation; rather, they occur in their deployment, maintenance, and ongoing development.
32%
Flag icon
This is not to say that architecture plays no role in supporting the proper behavior of the system. It certainly does, and that role is critical. But the role is passive and cosmetic, not active or essential. There are few, if any, behavioral options that the architecture of a system can leave open.
32%
Flag icon
A software system that is hard to develop is not likely to have a long and healthy lifetime. So the architecture of a system should make that system easy to develop, for the team(s) who develop it.
32%
Flag icon
This is likely the reason why so many systems lack good architecture: They were begun with none, because the team was small and did not want the impediment of a superstructure.
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
deployment strategy is seldom considered during initial development. This leads to architectures that may make the system easy to develop, but leave it very difficult to deploy.
32%
Flag icon
For example, in the early development of a system, the developers may decide to use a “mi...
This highlight has been truncated due to consecutive passage length restrictions.
33%
Flag icon
the number of micro-services has become daunting; configuring the connections between them, and the timing of their initiation, may also turn out to be a huge source of errors.
33%
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.
33%
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.
33%
Flag icon
good software architecture communicates the operational needs of the system.
33%
Flag icon
Architecture should reveal operation. The architecture of the system should elevate the use cases, the features, and the required behaviors of the system to first-class entities that are visible landmarks for the developers. This simplifies the understanding of the system and, therefore, greatly aids in development and maintenance.
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
A carefully thought-through architecture vastly mitigates these costs. By separating the system into components, and isolating those components through stable interfaces, it is possible to illuminate the pathways for future features and greatly reduce the risk of inadvertent breakage.
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.