I need to know why we need to avoid circular dependencies? In the real world if we think, circular dependencies are pretty much important. Like one friend needs something from other friend and the other needs something from this friend, so its kind of circular right?
Then why is circular dependency a bad design? If we really need to avoid this then what is the best possible design in Object oriented world for such a situation?
The problem with circular dependencies is rather like the chicken and egg problem.
If you depend on me setting something up, and I depend on you setting something up, how do we start?
The corollary of this is how do we end - if I have a reference to your resource and you have a reference to mine, I can never clean up because that would break you, and you cannot clean up because that would break me.
The answer in both cases is to introduce a middleman, passing the dependency from one of the parties to him, So if you passed your resource on to the middleman, you would depend on me and the middleman, and I would depend on the middleman. Thus you can clean up because you now hold no resource, and I can clean up because no-one depends on me, and then the middleman can clean up.
You need to realize that a circular dependency implies that you can use only the corresponding circular dependent classes together: if you have a circular dependency between, say, A
and B
, you cannot use A
or B
independently in any program. To stick with your problem: surely, you don't need the other two friends to exist! All you need is some way to refer to some and interact with them in a way which may be constrained over their actual abilities.
However, it often is possible to have objects of classes use each other without cause a circular dependency. To this end it is important to determine what actually causes a dependency between two class/components (these are not entirely equivalent but providing a thorough definition would be somewhat lengthy). A
depends on B
under these conditions:
A
contains a member of type B
.A
derives from type B
.A
uses a value of type B
as part of a function signature.A
uses B
in its implementation.When you have a cyclic dependency between two classes, there may be ways to break this dependency. Often, the dependency can be broken by splitting one of the two classes into a base class and a derived class with the base class not depending on the other class. There are a number of other approaches to break dependency cycles. John Lakos's "Large Scale C++" (1996) is essentially all about break dependency cycles and motivating why cyclic dependencies are bad (I guess, he would disagree with this simplifying characterization).
... and, yes, cyclic dependencies are bad:
The above is formulated with a view taken from a C++ perspective. Some of the causes of circular dependencies may not exist [directly] in C but the same concepts roughly apply to C, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With