2009-09-19 5 views
20

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

+0

[Здесь] (https://www.michaelsafyan.com/tech/design/patterns/singleton) является хорошим чтением на singleton, являющимся анти-шаблоном. – RBT

ответ

35

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

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

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

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

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

+0

Итак, вы имеете в виду, что синглтоны * никогда не могут быть использованы в реальных проектах (а определение синглтона в реальном проекте автоматически приравнивается к запаху кода независимо от варианта использования)? – Pacerier

+0

Я чувствую запах тролля ... –

+0

Не воздерживайтесь от пахнущего себя тогда. В вашем ответе говорится, что синглеты используются только для кода «начальной фазы» и должны учитываться во всех зрелых проектах, которые растут больше. Итак, вы имеете в виду, что синглтоны никогда не могут быть использованы для использования в этих проектах или существуют ли действующие варианты использования? – Pacerier

3

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

7

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

+1

@Nate, это звучит интересно, не могли бы вы привести конкретный пример? – eric2323223

+0

Есть ли авторитетные источники для вашего иска? Почему бы не разделить экземпляры JRE на отдельные экземпляры синглетонов? – Pacerier

+0

@ Pacerier http://www.oracle.com/technetwork/articles/java/singleton-1577166.html Отдельные JRE с использованием отдельных экземпляров singleton - это ожидаемый случай - проблема в одном JRE может иметь несколько загрузчиков классов и, следовательно, несколько экземпляров singleton , – Nate

18

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

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