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