$ obj = CLASS :: getInstance (). Em seguida, injetamos dependências usando setters e executamos a inicialização usando $ obj-> initInstance ();
Eu acho que você está tornando isso mais difícil do que precisa ser. Podemos injetar dependências muito bem através do construtor - e se você tiver muitas delas, use uma estrutura semelhante a dicionário para poder especificar quais você deseja usar:
$obj = new CLASS(array(
'Frobnicator' => (),
'Foonicator' => (),
));
E dentro do construtor, você pode garantir consistência da seguinte forma:
if (!array_key_exists('Frobnicator', $args)) {
throw new Exception('Frobnicator required');
}
if (!array_key_exists('Foonicator', $args)) {
$args['Foonicator'] = new DefaultFoonicator();
}
$args
pode então ser usado para definir membros privados conforme necessário.
Quando feito inteiramente dentro do construtor, nunca haverá um estado intermediário onde $obj
exista, mas não seja inicializado, como ocorreria no sistema descrito na pergunta. É melhor evitar esses estados intermediários, porque você não pode garantir que o objeto sempre será usado corretamente.