I think these are orthogonal and can be used together. Let me show you an example I recently came across at work:
We were using the Spring framework in Java for DI. A singleton class (Parent
) had to instantiate new objects of another class (Child
), and those had complex collaborators:
@Component
class Parent {
// ...
@Autowired
Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
this.dep1 = dep1;
this.dep2 = dep2;
}
void method(int p) {
Child c = new Child(dep1, dep2, ..., depN, p);
// ...
}
}
In this example, Parent
has to receive DepX
instances only to pass them to the Child
constructor. Problems with this:
Parent
has more knowledge of Child
than it shouldParent
has more collaborators than it shouldChild
involves changing Parent
This is when I realized a Factory
would fit here perfectly:
Child
class, as seen by Parent
Child
, which can be centralized in the DI configuration.This is the simplified Parent
class and the ChildFactory
class:
@Component
class Parent {
// ...
@Autowired
Parent(ChildFactory childFactory) {
this.childFactory = childFactory;
}
void method(int p) {
Child c = childFactory.newChild(p);
// ...
}
}
@Component
class ChildFactory {
// ...
@Autowired
Parent(Dep1 dep1, Dep2 dep2, ..., DepN depN) {
this.dep1 = dep1;
this.dep2 = dep2;
// ...
this.depN = depN;
}
Child newChild(int p) {
return new Child(dep1, dep2, ..., depN, p);
}
}