Ca sert à faciliter le remplacement de services par d'autres services, et en particulier par des Mocks pour le test.
Exemple: tu écris un client qui appelle deux services quelconques
Code :
public class ZeClient { private DbManagerInterface dbMgr; private ExternalServiceInterface extService; }
|
Sans IoC, ta classe client va instancier elle-même dbMgr et extService (via des Factory par ex).
Avec IoC, l'instanciation se fait en-dehors de ta classe.
Celle-ci ne va que conserver les instances existantes déjà créées. On injecte ces instances via le constructeur ou via des setters
Code :
public class ZeClient { private DbManagerInterface dbMgr; private ExternalServiceInterface extService; public ZeClient(DbManagerInterface dbMgr, ExternalServiceInterface extSrv){ this.dbMg= dbMgr; this.extService = extSrv; } public void setExtService(ExternalServiceInterface extSrv) { this.extSrv = extSrv; } public void setDbMgr(DbManagerInterface dbMgr) { this.dbMgr = dbMgr; } }
|
Il faut imaginer que dans une vraie application, ma classe ZeClient peut avoir facilement 5 ou 6 services (voire bcp plus), qui eux-mêmes appellent plusieurs services.
Du coup, dans une classe de test, quand j'instancie ZeClient, j'instancie au préalable tout l'arbre de dépendances des services dont il dépend potentiellement (même si dans mon test, je n'en utilise en réalité qu'un seul). Ca a deux inconvénients:
1. ZeClient embarque avec lui tous les services qu'il instancie. Sauf à modifier un fichier de mapping interface<->implémentation, on ne peut pas changer les services dbMgr et extService sans avoir à modifier le code de ZeClient.
2. Pour un test qui se veut unitaire de ZeClient, je suis obligé de créer tout l'univers: certains services, avant d'être utilisables, peuvent être pénibles à configurer, par ex, pour une base de donnée et un service externe, il faut préalablement que la base et le service en question existent sur le réseau et répondent correctement. Pour peu que chacun des services que ZeClient utilise appelle lui-même d'autres services, il faut tout configurer et il faut que tout fonctionne avant même de pouvoir lancer le moindre test. On ne fait plus de l'unitaire, mais de l'intégration, alors qu'on voudrait pouvoir juste les mocker pour retourner une valeur donnée quelconque.
Avec IoC, parce que ZeClient n'instancie plus rien lui-même, on peut créer les mocks, les instancier soi-même, et les injecter via le constructeur ou les setteurs.
Message édité par el muchacho le 05-09-2010 à 17:18:19
---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien