$obj = CLASS::getInstance(). Then we inject dependencies using setters and perform starting initialization using $obj->initInstance();
Penso che tu stia rendendo questo più difficile di quanto dovrebbe essere. Siamo in grado di iniettare le dipendenze nel costrut- tore, e se ne hai molte, basta usare una struttura simile a un dizionario per poter specificare quali usare:
$obj = new CLASS(array(
'Frobnicator' => (),
'Foonicator' => (),
));
E all'interno del costruttore, puoi garantire la coerenza in questo modo:
if (!array_key_exists('Frobnicator', $args)) {
throw new Exception('Frobnicator required');
}
if (!array_key_exists('Foonicator', $args)) {
$args['Foonicator'] = new DefaultFoonicator();
}
$args
può quindi essere utilizzato per impostare i membri privati secondo necessità.
Se fatto interamente all'interno del costruttore in questo modo, non ci sarà mai uno stato intermedio in cui $obj
esiste ma non è inizializzato, come ci sarebbe nel sistema descritto nella domanda. È meglio evitare tali stati intermedi, perché non è possibile garantire che l'oggetto venga sempre utilizzato correttamente.