So far we have gone through defining component and understanding what makes a component in previous chapters. In this post we start looking into principle that talk about the relationships between component. Let’s start with the acyclic dependency principle.
Allow no cycles in the component dependency graph
Robert Martin
A very common scenario that we developers face – We are working on a project, make some code changes, verify it’s working, so log out for day/commit the changes. Next day or few days later, we find that our integration tests are failing! Root cause comes out to be a change in one of our dependencies. This leads to either reverting our change or working on fix. The author calls this “morning after syndrome”.
Solution to this problem of running into frequent changes caused by changes in dependencies – The Weekly Build
The Weekly Build
As per this, developers work for 4 days in a week on their code and on fifth day they integrate their changes and build the system.
Now this could work when the team is small/the system is small so there are fewer teams. But when the system would grow, components and teams owning those components would grow. Eventually we would find that it takes more time to integrate and so pushing the integration days one day back. Ultimately a build per week won’t be sufficient and we would starting doing a build every two weeks. This could increase to month!
Clearly this solution cannot work for large systems.
Dependency Cycles elimination
The solution is to partition the development environment into releasable components. Each component could have its release versions with each change. The components consuming these changed components can then decide to move to new version or keep using the previous ones. This reduces the dependencies between teams and they can work independently.
The key for this approach to work is – When components depend on other components, there should be no cycles.
Say we have three components A, B, C. A depends on B, B depends on C. There will be a cycle if C would depend on A. If there is no cycle, any changes in A would force changes in B and C. Any change in B would only force C to change, A is safe. Any change in C would not force any change in A or B.
However if there is a cycle, then any change in A, B or C would need changes in all components.
So if there are cycles in the way our component depends on each other, we need to break it –
- Use DIP (Dependency Inversion Principle), invert dependency by using interfaces.
- Add the common classes between two components to a third component and then depend on that component.
Top Down Design
When we start building the system, we could be grouping classes based on usability. Few iterations later, we might worry about reusability of components and start moving around classes by creating new components and new dependencies between them. We can see the component structure keeps on evolving based on the requirements at each stage of our development. And so we cannot design this structure at the beginning in top down manner.
Thanks for stopping by! I hope this gives a good preview into acyclic dependency principle. Eager to hear your thoughts and chat, please leave comments below and we can discuss.