Hello,
C'est plutôt une bonne pratique de passer les dépendances dans le constructeur
Comme tu l'as justement noté, cela rend le code plus testable, et aussi plus maintenable car s'il y a besoin de changer l'implémentation concrète d'une dépendance, ce n'est plus dans la classe qui en dépend qu'on va modifier quelque chose mais à l'extérieur. Cela la rend moins fragile et plus robuste aux changements.
Mais tout n'est pas si simple, car il y a deux types de dépendances : celles dont on veut qu'elles soient présentes tout au long de la vie de l'objet, et celles dont on n'a besoin que ponctuellement. Dans ton code, on n'a par exemple pas forcément envie de garder une connexion base de données ouverte tout le temps et donc pas envie que les objets "du dessus" se la trimballent à vie pour qu'au final elle soit utilisée très épisodiquement dans un objet "du dessous".
Dans ce cas, on peut donc utiliser une
dépendance capable de créer des dépendances, à savoir une Factory. La Factory elle-même peut être injectée dans le constructeur et traitée comme une dépendance "à vie", mais on pourra l'appeler quand on veut pour qu'elle fabrique des rejetons à durée de vie taillée sur mesure. Attention toutefois à ne pas abuser des Factory qui restent adaptées à un usage très particulier - la plupart du temps, passer une dépendance normale suffit, surtout dans les contextes applicatifs ou le process ne dure que quelques instants comme une application web.
Dans ton cas, on pourrait donc avoir la chaîne de dépendances
new Controller(new Model(new ConnectionFactory(...)))
A noter que dans cet assemblage, ce n'est pas le Controller qui connait la classe ConnectionFactory concrète à instancier, le controller n'a pas de dépendance directe sur cette classe. C'est le
contexte global, un niveau au-dessus, qui instancie le Controller et tous les objets de la chaîne. C'est ce qu'on appelle une Composition Root : un endroit unique situé à l'entrée de l'application et qui va composer toute notre grappe de dépendances. J'imagine qu'on doit pouvoir faire ça en PHP en se branchant sur l'arrivée d'une requête HTTP. Sinon, des frameworks d'injection de dépendance (IoC Container) doivent permettre de le faire. Ces frameworks offrent des facilités supplémentaires pour gérer la résolution l'assemblage des dépendances entre elles.
Partager