Dans certains de mes codes, j'ai une usine statique similaire à celle-ci:
public class SomeFactory {
// Static class
private SomeFactory() {...}
public static Foo createFoo() {...}
public static Foo createFooerFoo() {...}
}
Lors d'une révision du code, il a été proposé que ce soit un singleton et injecté. Donc, cela devrait ressembler à ceci:
public class SomeFactory {
public SomeFactory() {}
public Foo createFoo() {...}
public Foo createFooerFoo() {...}
}
Quelques points à souligner:
- Les deux usines sont apatrides.
- La seule différence entre les méthodes est leur portée (instance vs statique). Les implémentations sont les mêmes.
- Foo est un bean qui n'a pas d'interface.
Les arguments que j'avais pour devenir statique étaient:
- La classe est sans état, elle n'a donc pas besoin d'être instanciée
- Il semble plus naturel de pouvoir appeler une méthode statique que d'avoir à instancier une fabrique
Les arguments pour l'usine en tant que singleton étaient les suivants:
- C'est bon de tout injecter
- Malgré l'apatridie de l'usine, le test est plus facile avec l'injection (facile à se moquer)
- Il faut se moquer lors du test du consommateur
J'ai de sérieux problèmes avec l'approche singleton car elle semble suggérer qu'aucune méthode ne devrait jamais être statique. Cela semble également suggérer que des utilitaires tels que ceux-ci StringUtils
devraient être enveloppés et injectés, ce qui semble idiot. Enfin, cela implique que je devrai se moquer de l'usine à un moment donné, ce qui ne semble pas correct. Je ne peux pas penser au moment où je devrais me moquer de l'usine.
Que pense la communauté? Bien que je n'aime pas l'approche singleton, je ne semble pas avoir d'argument terriblement fort contre.
DateTime
et File
sont notoirement difficiles à tester pour exactement les mêmes raisons. Par exemple, si vous avez une classe qui définit la Created
date DateTime.Now
dans le constructeur, comment allez-vous créer un test unitaire avec deux de ces objets qui ont été créés à 5 minutes d'intervalle? Et des années à part? Vous ne pouvez vraiment pas le faire (sans beaucoup de travail).
private
constructeur et une getInstance()
méthode? Désolé, incorrigible nit-picker!