In alcuni dei miei codici, ho una fabbrica statica simile a questa:
public class SomeFactory {
// Static class
private SomeFactory() {...}
public static Foo createFoo() {...}
public static Foo createFooerFoo() {...}
}
Durante una revisione del codice, è stato proposto che questo dovesse essere un singleton e iniettato. Quindi, dovrebbe apparire così:
public class SomeFactory {
public SomeFactory() {}
public Foo createFoo() {...}
public Foo createFooerFoo() {...}
}
Alcune cose da evidenziare:
- Entrambe le fabbriche sono apolidi.
- L'unica differenza tra i metodi sono i loro ambiti (istanza vs statica). Le implementazioni sono le stesse.
- Foo è un bean che non ha un'interfaccia.
Gli argomenti che ho avuto per diventare statico sono stati:
- La classe è senza stato, pertanto non è necessario creare un'istanza
- Sembra più naturale poter chiamare un metodo statico piuttosto che dover istanziare una fabbrica
Gli argomenti per la fabbrica come singleton erano:
- È bello iniettare tutto
- Nonostante l'apolidia della fabbrica, i test sono più facili con l'iniezione (facile da deridere)
- Dovrebbe essere deriso durante il test del consumatore
Ho alcuni seri problemi con l'approccio singleton poiché sembra suggerire che nessun metodo dovrebbe mai essere statico. Sembra anche suggerire che programmi di utilità come quelli StringUtils
dovrebbero essere avvolti e iniettati, il che sembra sciocco. Infine, implica che dovrò deridere la fabbrica ad un certo punto, il che non sembra giusto. Non riesco a pensare a quando dovrei prendere in giro la fabbrica.
Cosa pensa la comunità? Anche se non mi piace l'approccio singleton, non mi sembra di avere un argomento terribilmente forte contro di esso.
DateTime
e File
sono notoriamente difficili da testare esattamente per le stesse ragioni. Se hai una classe, ad esempio, che imposta la Created
data DateTime.Now
nel costruttore come fai a creare un unit test con due di questi oggetti che sono stati creati a 5 minuti di distanza? E gli anni a parte? Non puoi davvero farlo (senza molto lavoro).
private
costruttore e un getInstance()
metodo? Mi dispiace, incorreggibile raccoglitore di nit!