Синглтонский дизайн: ловушки

В настоящее время меня очень интересует этот "шаблон дизайна". Я не уверен, хотя, если есть недостатки, использующие эту строгую глобальную реализацию. Итак, когда вы думаете, что не применять синглтон в приложении?

Ответ 1

Синглтон - это, как правило, плохая идея, если вы проводите модульное тестирование, и, как правило, плохая идея не выполнять модульное тестирование (или BDD или тестирование приемочных испытаний).

Создание объектов с глобальным состоянием означает, что единицы измерения, которые вы записываете с участием этих объектов, будут изолированы и не пересекаются друг с другом. Вместо этого вам придется беспокоиться о сбросе состояния для каждого теста и верить мне... это никогда не делается в 100% случаев. Если вы не reset глобальное состояние, тогда вы начинаете очень странно и трудно отлаживать ошибки в тестах, которые теряют время.

Глобальное состояние также увеличивает сцепление в коде и очень затрудняет рефакторинг.

Идеальный метод заключается в использовании контейнера IoC/DI (Spring, Guice и т.д.) для запроса объектов. У этих контейнеров часто есть способы создания объектов как "синглтоны", но у них также есть способы изменения этого поведения в зависимости от ситуации (например, модульное тестирование по сравнению с кодом вашего домена).

Все это зависит от размера вашей проблемы, конечно. Если вы взламываете 4-классную испытательную установку, чтобы попробовать что-то, то идите вперед и используйте Singleton. Однако, как только этот проект берет на себя жизнь и становится все больше и сложнее, реорганизуйте Singleton вне.

Ответ 2

Google Tech Talks некоторое время назад была хорошей презентацией о Global State and Singletons. Статический шаблон singleton является злым, потому что он вызывает нежелательные побочные эффекты и делает код неустойчивым. Статический singleton - это версия глобальных переменных OO.

Решение состоит в том, чтобы просто создать один экземпляр объекта и передать его своим пользователям посредством инъекции зависимостей. DI, такие как Guice, упрощают определение хорошего типа синглетонов (в Guice просто комментируют класс с @Singleton). Был аналогичный Tech Talk, называемый "Не ищите вещи!" , в котором обсуждалось больше.

Ответ 3

В дополнение к проблемам тестирования и дизайна, упомянутым в других сообщениях, есть проблемы с Singletons и загрузчиками классов. Синглтоны на самом деле не "одиночные" для JVM или приложения - они выполняют это через статическое свойство, что на самом деле означает, что для каждого класса есть один. Если в большинстве серверов приложений есть несколько загрузчиков классов - каждое отдельное приложение получает новый загрузчик классов, в EJB используются даже несколько уровней загрузчиков классов. Один экземпляр singleton загружается для каждого загрузчика классов - который в зависимости от того, что вы делаете с синглоном, может не дать ожидаемых результатов.

Ответ 4

Я бы использовал Singleton очень редко. Из-за своей природы (статические, глобальные объекты) их сложно использовать при тестировании вашего кода. В конечном итоге вам нужно выполнить некоторую синхронизацию или создать некоторые механизмы повторной инициализации, чтобы вы могли получить новую версию для каждого unit test. Есть случаи, которые имеют смысл - скажем, например, глобальный класс конфигурации, - но их гораздо меньше, чем кажется людям, которые, как кажется, верят в то, что люди, о которых никто не знает, Я знаю, что прошел фазу, где повсюду я видел приложения синглетного рисунка. Теперь я избегаю этого, где могу, и отменил его с помощью рефакторинга в моем коде, поскольку я сталкиваюсь с ненужной реализацией.