Dead factory - Alexander Kaiser - Ce fichier est sous licence Creative Commons Attribution 2.0 Generic.
Le Factory Method pattern est, à mon avis, l’un des design patterns de création les plus utiles.
Il nous permet de déléguer la création d’un objet à une classe dédiée, et ainsi d’encapsuler toute la logique de cette création qui n’est souvent pas directement liée à la responsabilité de la classe.
1) Exemple simple : Considérons le code suivant :
| |
La première classe est un véritable objet métier : elle est construite à partir de certaines propriétés, possède une logique métier. Sa responsabilité unique est d’exécuter la logique métier. Elle ne devrait pas embarquer de préoccupations infrastructurelles (comme une connexion à la base de données par exemple).
La deuxième classe est la factory elle-même, qui gère le processus complet de création de notre BusinessObject. Sa responsabilité inclut de récupérer les données d’un repository et d’appeler le constructeur de la classe métier.
La troisième classe est un simple runner, qui instancie la factory, obtient l’objet métier de celle-ci, et exécute ce que le programme est censé faire. Grâce au Factory Method Pattern, le Runner n’est pas pollué par la logique de construction, tout est délégué à l’objet factory.
2) Améliorer la testabilité du système : Évidemment, en séparant les responsabilités de votre code en différents modules, vous améliorez, de facto, la testabilité de votre programme. Mais dans certains cas, vous pouvez utiliser le factory method pattern comme moyen d’utiliser un TestDouble là où vos techniques habituelles de mocking ne peuvent pas s’appliquer. Par exemple, quand votre code consomme un objet externe, et que cet objet n’a pas d’interface, comme ce NetworkMessage.
| |
Comme vous pouvez le voir, la classe principale repose sur DateTime.Now, ce qui rend le code qui en dépend assez compliqué à tester.
Voici notre propre NetworkClient, sans factory pour le NetworkMessage :
| |
Ici, pour pouvoir tester chaque chemin d’exécution de notre client, nous devons savoir précisément comment la bibliothèque externe se comporte en interne, et même utiliser des Microsoft.Fakes pour créer des shims de System.DateTime. C’est beaucoup de code de test qui n’est pas vraiment pertinent, car c’est hors de notre périmètre. De plus, nous voulons juste contrôler la sortie du NetworkMessage pour nous assurer que notre client réseau se comporte correctement. Pour y parvenir, nous pouvons ajouter une factory à notre client :
| |
Et tester devient vraiment facile, en implémentant une autre factory, qui crée un objet qui hérite de notre objet externe :
| |
Dans cet article, nous avons vu que le Factory Method pattern nous aide à respecter le Single Responsibility Principle de SOLID, et peut nous aider avec l’intégration de code externe/legacy, en nous fournissant un moyen d’améliorer la testabilité.
Note : tout le code de cet article est accessible sur ce repository github
Commentaires
💬 Les commentaires sont partagés entre toutes les versions linguistiques de cet article.