I'm thinking specifically of the Strategy pattern (Design Patterns, GoF94), where it is suggested that the context passed to the strategy constructor can be the object which contains the strategy (as a member) itself. But the following won't work:
//analysis.h
class StrategyBase;
class Strategy1;
class Strategy2;
class Analysis
{
...
void ChooseStrategy();
private:
StrategyBase* _s;
...
};
//analysis.cpp
void Analysis::ChooseStrategy()
{
if (...) _s = new Strategy1(this);
else if (...) _s = new Strategy2(this);
...
}
//strategy.h
#include analysis.h
...
and then StrategyBase and its subclasses then access the data members of Analysis.
This won't work because you can't instantiate Strategy* classes before they've been defined. But its definition depends on that of Analysis. So how are you supposed to do this? Replace ChooseStrategy with
void SetStrategy(StrategyBase* s) { _s = s; }
and do the instantiation in files which #include both analysis.h and strategy.h? What's best practice here?
To resolve circular dependencies: Then there are three strategies you can use: Look for small pieces of code that can be moved from one project to the other. Look for code that both libraries depend on and move that code into a new shared library. Combine projectA and projectB into one library.
A simple way to break the cycle is by telling Spring to initialize one of the beans lazily. So, instead of fully initializing the bean, it will create a proxy to inject it into the other bean. The injected bean will only be fully created when it's first needed.
A circular dependency occurs when two classes depend on each other. For example, class A needs class B, and class B also needs class A. Circular dependencies can arise in Nest between modules and between providers. While circular dependencies should be avoided where possible, you can't always do so.
Analyze cyclic dependenciesFrom the main menu, select Code | Analyze Code | Cyclic Dependencies. In the Specify Cyclic Dependency Analysis Scope dialog, select the scope of files that you want to analyze. Select the Include test sources option if you want to analyze your test code together with the production code.
You will always have circular dependencies in the State/Strategy Pattern, except for very general States/Strategies. But you can limit the in-size (Lakos) use of the respective other class such that it compiles, at least:
Analysis
(analysis.h
or strategies.h
)StrategyBase
and subclasses (don't inline methods that use Analysis
) (strategies.h
)Analysis
(may already use inline methods that use strategies) (analysis.h
)Analysis
and the strategy classes' non-inline methods (analysis.cpp
)analysis.cpp
also needs to include strategy.h
to pick up the full definitions of the strategies. Since it's a source file there's no circular dependency.
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