I understand the factory pattern on a simple form but not much if the class requires multiple nested dependencies. E.g.,
$cfg = new Cfg();
$cfg->setA('a');
$cfg->setB('b');
$qux = new Qux('x');
$bar = new Bar($cfg, $qux);
$foo = new Foo($cfg, $bar);
In the above example, how do you properly make a factory pattern for class Foo
so that when you run $factory->build();
you get an instance of Foo
with all its dependencies?
You have to go the other way around. By the time client code calls .build
on the factory object, everything should be ready, hence .build
rarely takes any parameters, and if it does, typically they serve as auxiliaries: logging, some kind of debug-time helpers, whatsoever. It does not meant that you must keep your .build
parameterless though.
So the question is how does one get to the parameterless .build
, right? Well, either AbstractFactory
pattern - a factorory of factories, or "a higher order factory", if it makes more sense for you. It may take implementations. Normally, for big and rather complex projects, it would take some kind of ServiceLocator
- basically, a DI-container. It might be globall and "know" all existing services (though, I won't recommend it), or it might be more precise (like module-wide, or namespace-wide - depending upon circumstances). The other options is plain old currying - a concept from the functional programming, which can be relatively easy adopted (as soon as you get it, of course) to your code; essentially, it does what AbstractFactory
would do, bypassing verbosity.