D'autres ont très bien expliqué le problème des singletons en général. Je voudrais juste ajouter une note sur le cas spécifique de Logger. Je suis d'accord avec vous que ce n'est généralement pas un problème d'accéder à un enregistreur (ou au root logger, pour être précis) en tant que singleton, via une méthode statique getInstance()
ou getRootLogger()
. (sauf si vous voulez voir ce qui est consigné par la classe que vous testez - mais d'après mon expérience, je peux difficilement me souvenir de tels cas où cela était nécessaire. Là encore, pour d'autres, cela pourrait être une préoccupation plus urgente).
IMO généralement un enregistreur singleton n'est pas un souci, car il ne contient aucun état pertinent pour la classe que vous testez. Autrement dit, l'état de l'enregistreur (et ses modifications possibles) n'ont aucun effet sur l'état de la classe testée. Cela ne rend donc pas vos tests unitaires plus difficiles.
L'alternative serait d'injecter le logger via le constructeur, dans (presque) toutes les classes de votre application. Pour la cohérence des interfaces, il doit être injecté même si la classe en question ne consigne rien pour le moment - l'alternative serait que lorsque vous découvrez à un moment donné que vous devez maintenant enregistrer quelque chose de cette classe, vous avez besoin d'un enregistreur, donc vous devez ajouter un paramètre de constructeur pour DI, cassant tout le code client. Je n'aime pas ces deux options et je pense que l'utilisation de DI pour la journalisation ne ferait que me compliquer la vie afin de me conformer à une règle théorique, sans aucun avantage concret.
Donc, ma conclusion est la suivante: une classe qui est utilisée (presque) universellement, mais qui ne contient pas d'état pertinent pour votre application, peut être implémentée en toute sécurité en tant que Singleton .