Есть ли случаи, когда синглтон - лучший вариант?

На этом сайте много дискуссий о том, почему следует избегать синглтонов, но есть ли случаи, когда синглтон имеет смысл и является лучшим вариантом?

Пример, в котором я считаю, что синглтон является лучшим вариантом, - это реализация Карта идентичности, когда вам нужно отслеживать все модели, которые уже были загружены из базы данных в вашем слое отображения. В этом случае важно, чтобы карта была фактически глобальной, чтобы весь клиентский код использовал один и тот же экземпляр карты, и все они обращались к одному и тому же списку загруженных моделей. Кажется, что самое простое решение - реализовать класс как одноэлементный (или как статические методы). Это лучший подход или есть другой способ?

Есть ли другие случаи, когда можно использовать синглтон, или они всегда плохие?

Повышение качества Laravel с помощью принципов SOLID: Лучшие практики и примеры
Повышение качества Laravel с помощью принципов SOLID: Лучшие практики и примеры
Когда мы говорим о том, как сделать следующий шаг в качестве разработчика, мы должны понимать, что качество кода всегда является основным фокусом на...
Принципы SOLID - лучшие практики
Принципы SOLID - лучшие практики
SOLID - это аббревиатура, обозначающая пять ключевых принципов проектирования: принцип единой ответственности, принцип "открыто-закрыто", принцип...
2
0
688
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Синглтоны (и подобные) используются в языках, которые не допускают статические элементы интерфейса, например, в .NET. Предоставляя синглтон, вы получаете экземпляр, который может предоставлять интерфейс в качестве экземпляра. Итак, в .NET примеры могут быть такими:

  • Comparer<T>.Default - предоставляет реализацию IComparer<T> для сортировки T
  • EqualityComparer<T>.Default - предоставляет реализацию IEqualityComparer<T> для хеширования / проверки равенства T

Это средство для достижения цели; это не то, что мы пытаемся сделать, а просто разумное «как».

Что касается примера «карты идентичности», лично я бы предпочел оставить ее в экземпляре и сделать этот экземпляр доступным для всего моего кода. Помимо всего прочего, это помогает тестируемости, если вы можете отбрасывать карту между тестами или иметь возможность (позже) иметь несколько карт идентичности одновременно.

Подумайте о случае, когда вы хотите записывать различные события в приложении в один файл. В этом случае будет полезен одноэлементный класс Log. Поскольку разные части приложения будут обращаться к одному и тому же экземпляру класса Log.

Ответ принят как подходящий

Синглтоны действительно имеют свое применение. У них тоже есть свои злоупотребления, и есть множество причин, по которым они не нравятся или почему они затрудняют тестирование.

Вот небольшая защита паттерна Синглтон.

Иногда программе необходимо представлять или взаимодействовать с чем-то действительно уникальным. Пример - физический ресурс. Например, у вас не может быть более одного стандартного вывода. И представление процесса ОС (например, мидлет J2ME).

Синглтоны, такие как использование класса / интерфейса для инкапсуляции, и такие преимущества того, что в противном случае было бы голой глобальной переменной, того стоит.

Синглтоны имеют смысл, когда вы используете веб-программирование: обычно вам нужен только один экземпляр класса вывода страницы на запрос и один пользовательский объект для него. Однако базы данных разные - реализация разделения привилегий - хорошая причина для того, чтобы хотеть иметь более одного объекта db.

Я лично рекомендую никогда не кодировать класс как синглтон, если вы можете просто создать экземпляр одного объекта класса впоследствии. Это делает синглтоны очень редкими и часто ненужными в коде приложения. Это особенно верно при использовании фреймворков DI, таких как Spring.

Синглтоны действительно используются в качестве `` точек входа '' в фреймворках, но там правилом было бы использовать их как `` корневые синглтоны '' (в начале иерархии зависимостей) и позволить остальной части кода зависеть от этого синглтона как минимум возможный.

Синглтоны действительно имеют свое применение. Я бы резюмировал их полезность как:

«Синглтон должен использоваться для представления объекта, который, в соответствии с фундаментальной структурой или требованиями, может быть не более одного экземпляра; и есть данные или ресурсы, связанные с объектом, который влечет за собой измеримую стоимость». Вот что я имею в виду.

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

2) Многие виды использования синглтона можно заменить классом со всеми статическими методами и данными. Если вы можете сделать это без потери производительности, сделайте это.

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

Синглтоны следует использовать, когда вам нужен только один экземпляр и вы хотите обеспечить это с помощью дизайна. Это не следует использовать из-за глобального побочного эффекта он вызывает.

В вашем случае я думаю, что это имеет смысл, потому что вы хотите ограничить только один экземпляр класса.

Другие вопросы по теме