Search code examples
phpdesign-patternsfactoryfactory-pattern

Factory pattern for multiple nested dependencies?


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?


Solution

  • 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.