The Acyclic Dependencies Principle (ADP) is the first of three principles that deals with the relationships between components.
It says: ”Allow no cycles in the component dependency graph.”
If you draw the components and the dependencies between them and you are able to follow a dependency back to a component you have already visited, then it is a violation to ADP.
So why should you care about cyclic dependencies? Because their existence makes it very hard to split up responsibilities and work on different tasks in parallel without stepping on each other toes all the time. Take a closer look at ComponentH in Figure 1 above. The dependency to ComponentA makes it depend on every other component in the system. Since ComponentD depends on ComponentH, it also makes ComponentD depend on every other component in the system.
This makes it really hard to work with and release components D and H. But what would happen if we could remove the dependency from ComponentH to ComponentA? Then it would be possible to work with and release ComponentH in isolation. The person, or team, working with ComponentD could lift in new releases of ComponentH when they needed, and wait with taking in the new release if they had other more prioritized tasks to solve before moving to the new release.
How can we break a dependency such as the dependency from ComponentH to ComponentA? There are two options we can use:
- Apply the Dependency-Inversion Principle (the D in SOLID) and create an abstract base class or interface in ComponentH and inherit it in ComponentA. This will invert the dependency so that ComponentA depends on ComponentH instead.
- Create a new component – let’s call it ComponentI – that both ComponentA and ComponentH depends on. See figure 2 below.
It is easy to introduce cyclic dependencies. You need to keep track of the dependencies in your system and break cycles when they appear.