Others have well explained the problem with singles in general. I just wanted to add a note about a specific Logger case. I agree with you that it is usually not a problem to access the Logger (or the root logger, to be precise), as it is solid using the static method
getInstance() or
getRootLogger() . (unless you want to know what is being registered by the class you are testing), but, in my experience, I can hardly recall such cases when it was necessary. Again for others, this may be a more pressing issue).
IMO, as a rule, a singleton logger is not a concern, since it does not contain any state related to the class you are testing. That is, the state of the registrar (and its possible changes) does not affect the state of the tested class. Thus, it does not make testing your device difficult.
An alternative would be to enter the registrar through the constructor so that (almost) every single class in your application. For interface consistency, you should enter it even if the class in question does not register anything at present - an alternative would be that when you find at some point that you now need to register something from this class, you need a logger, so so you need to add a constructor parameter for the DI, breaking all the client code. I don’t like both of these options, and I feel that using DI for registration will simply complicate my life to fit the theoretical rule without any particular benefit.
So, my bottom line: a class that is (almost) used universally but does not contain a state that matches your application can be safely implemented as Singleton .
Péter Török Apr 18 2018-10-18T00: 00Z
source share