Другие очень хорошо объяснили проблему синглтонов в целом. Я просто хотел бы добавить примечание о конкретном случае Logger. Я согласен с вами, что обычно не проблема получить доступ к Регистратору (или корневому регистратору, если быть точным) как синглтону, через статический getInstance()
или getRootLogger()
метод. (если вы не хотите видеть, что регистрируется тестируемым вами классом - но по своему опыту я вряд ли могу вспомнить такие случаи, когда это было необходимо. Опять же, для других это может быть более насущной проблемой).
IMO обычно одноэлементный регистратор не вызывает беспокойства, поскольку он не содержит никакого состояния, относящегося к тестируемому классу. То есть состояние регистратора (и его возможные изменения) никак не влияют на состояние тестируемого класса. Так что это не усложняет ваши модульные тесты.
Альтернативой было бы внедрение регистратора через конструктор в (почти) каждый класс в вашем приложении. Для согласованности интерфейсов его следует вводить, даже если рассматриваемый класс в настоящее время ничего не регистрирует - альтернативой может быть то, что когда вы обнаружите в какой-то момент, что теперь вам нужно что-то регистрировать из этого класса, вам понадобится регистратор, таким образом вам нужно добавить параметр конструктора для DI, нарушив весь клиентский код. Мне не нравятся оба этих варианта, и я чувствую, что использование DI для регистрации просто усложнило бы мне жизнь, чтобы соответствовать теоретическому правилу, без какой-либо конкретной выгоды.
Итак, мой итог: класс, который используется (почти) повсеместно, но не содержит состояния, относящегося к вашему приложению, может быть безопасно реализован как Singleton .