Otros han explicado muy bien el problema con los singletons en general. Me gustaría agregar una nota sobre el caso específico de Logger. Estoy de acuerdo con usted en que generalmente no es un problema acceder a un registrador (o al registrador de raíz, para ser precisos) como un singleton, a través de un método estático getInstance()
o getRootLogger()
. (a menos que quiera ver lo que registra la clase que está probando, pero en mi experiencia difícilmente puedo recordar casos en los que fue necesario. De nuevo, para otros esto podría ser una preocupación más apremiante).
IMO generalmente un registrador de singleton no es una preocupación, ya que no contiene ningún estado relevante para la clase que está probando. Es decir, el estado del registrador (y sus posibles cambios) no tienen ningún efecto en el estado de la clase probada. Por lo tanto, no hace que las pruebas de su unidad sean más difíciles.
La alternativa sería inyectar el registrador a través del constructor, a (casi) cada clase en su aplicación. Para la coherencia de las interfaces, se debe inyectar incluso si la clase en cuestión no registra nada en la actualidad; la alternativa sería que cuando descubras en algún momento que ahora necesitas registrar algo de esta clase, necesitas un registrador , por lo tanto, necesita agregar un parámetro de constructor para DI, rompiendo todo el código del cliente. No me gustan estas dos opciones, y creo que usar DI para registrar me complicaría la vida solo para cumplir con una regla teórica, sin ningún beneficio concreto.
Así que mi conclusión es: una clase que se utiliza (casi) universalmente, pero no contiene un estado relevante para su aplicación, se puede implementar de forma segura como Singleton.
Soy nuevo en este diseño pattren, y me gustaría saber por qué quieres decir con "prueba" cuando dices especialmente en las pruebas? gracias de antemano. – AnixPasBesoin
Me refiero a pruebas de unidad/integración – Bozho