En algunos de mis códigos, tengo una fábrica estática similar a esta:
public class SomeFactory {
// Static class
private SomeFactory() {...}
public static Foo createFoo() {...}
public static Foo createFooerFoo() {...}
}
Durante una revisión de código, se propuso que este debería ser un singleton e inyectado. Entonces, debería verse así:
public class SomeFactory {
public SomeFactory() {}
public Foo createFoo() {...}
public Foo createFooerFoo() {...}
}
Algunas cosas a destacar:
- Ambas fábricas son apátridas.
- La única diferencia entre los métodos son sus ámbitos (instancia frente a estático). Las implementaciones son las mismas.
- Foo es un bean que no tiene una interfaz.
Los argumentos que tuve para volverme estático fueron:
- La clase no tiene estado, por lo tanto, no necesita ser instanciada
- Parece más natural poder llamar a un método estático que tener que crear una instancia de fábrica
Los argumentos para la fábrica como singleton fueron:
- Es bueno inyectar todo
- A pesar de la apatridia de la fábrica, las pruebas son más fáciles con la inyección (fácil de burlar)
- Se debe burlar al probar al consumidor
Tengo algunos problemas serios con el enfoque singleton ya que parece sugerir que ningún método debería ser estático. También parece sugerir que las utilidades como StringUtils
deberían ser envueltas e inyectadas, lo que parece una tontería. Por último, implica que tendré que burlarme de la fábrica en algún momento, lo que no parece correcto. No puedo pensar en cuándo necesitaría burlarme de la fábrica.
¿Qué piensa la comunidad? Si bien no me gusta el enfoque singleton, no parece tener un argumento terriblemente fuerte contra él.
DateTime
y File
son notoriamente difíciles de probar exactamente por las mismas razones. Si tiene una clase, por ejemplo, que establece la Created
fecha DateTime.Now
en el constructor, ¿cómo hace para crear una prueba unitaria con dos de estos objetos que se crearon con 5 minutos de diferencia? ¿Qué pasa con años de diferencia? Realmente no puedes hacerlo (sin mucho trabajo).
private
constructor y un getInstance()
método? Lo siento, ¡recolector de liendres incorregible!