Подтвердить что ты не робот

Наиболее распространенные примеры злоупотребления однопользовательским классом

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

4b9b3361

Ответ 1

Не используйте синглтон для чего-то, что может превратиться в мультипликативный ресурс.

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

Типичный пример: "Существует только одно соединение с базой данных, которое имеет это приложение, поэтому оно является одноэлементным". - Плохая идея. Возможно, вы захотите иметь несколько соединений в будущем. Лучше создать пул соединений с базой данных и заполнить его всего одним экземпляром. Действует как синглтон, но у всего другого кода будет доступный код для доступа к пулу.

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

Ответ 2

Ну синглтоны по большей части просто делают вещи статичными в любом случае. Таким образом, вы либо фактически делаете данные глобальными, и все мы знаем, что глобальные переменные плохи, или вы пишете статические методы, и что это не очень OO сейчас?

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

Ответ 3

Я знаю, что многие ответили "когда у вас более одного" и т.д.

Поскольку оригинальный плакат хотел список случаев, когда вы не должны использовать Singletons (а не главную причину), я буду звонить с помощью:

Всякий раз, когда вы используете его, потому что вам запрещено использовать глобальный!

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

Ответ 4

Я виноват в большом году несколько лет назад (к счастью, с тех пор я узнал о своем сокращении).

Что случилось, так это то, что я пришел на проект настольного приложения, который был преобразован в .Net из VB6 и был настоящим беспорядком. Такие вещи, как 40-страничные (печатные) функции и отсутствие реальной классовой структуры. Я построил класс для инкапсуляции доступа к базе данных. Не настоящий уровень данных (пока), просто базовый класс, который может использовать реальный уровень данных. Где-то я получил яркую идею сделать этот класс синглом. Он работал нормально в течение года или около того, а затем нам также нужно было создать веб-интерфейс для приложения. Синглтон оказался огромным узким местом для базы данных, поскольку все веб-пользователи должны были использовать одно и то же соединение. Снова... извлеченный урок.

Оглядываясь назад, вероятно, на самом деле это был правильный выбор на короткое время, поскольку он заставил других разработчиков более дисциплинированно использовать его и информировал о проблемах, которые ранее не были проблемой в мире VB6. Но я должен был изменить его назад через несколько недель, прежде чем мы слишком много накопили вокруг него.

Ответ 5

Вот проворство моего друга Алекс Миллера... Он точно не перечисляет "когда вы НЕ должны использовать одноэлементный", но это всеобъемлющий, отличный пост и утверждает, что в редких случаях следует использовать только одноэлемент, если вообще.

Ответ 6

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

Посмотрите, как работает Injection Dependency. Он решает те же проблемы, но гораздо более полезным способом - на самом деле, вы обнаружите, что это относится ко многим другим частям вашего дизайна.

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

Ответ 7

Я пытаюсь использовать только один синглтон - инверсию объекта управления/сервиса.

IService service = IoC.GetImplementationOf<IService>();

Ответ 8

Одна из вещей, которые стремятся сделать это кошмаром, - это если она содержит глобальное состояние modifiable. Я работал над проектом, где Синглтоны использовались повсюду для вещей, которые должны были быть решены совершенно по-другому (переходите к стратегиям и т.д.). "Де-одиночная тонизация" была в некоторых случаях основным переписанием частей система. Я бы сказал, что в большей части случаев, когда люди используют Синглтон, он просто ошибочен, так как он выглядит хорошо, в первую очередь, но превращается в проблему, особенно при тестировании.

Ответ 9

Иногда вы предполагаете, что будет только одна вещь, тогда вы оказываетесь неправы.

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

// Its our database! We'll never need another
class Database
{
};

Но подождите! Ваш босс говорит, подключитесь к какой-то другой базе данных парней. Предположим, вы хотите добавить phpbb на веб-сайт и хотите подделать свою базу данных, чтобы интегрировать некоторые ее функции. Должны ли мы создать новый синглтон или другой экземпляр базы данных? Большинство людей согласны с тем, что предпочтительным является новый экземпляр того же класса, нет дублирования кода.

Лучше иметь

Database ourDb;
Database otherDb;

чем копировать прошлую базу данных и сделать:

// Copy-pasted from our home-grown database.
class OtherGuysDatabase
{
};

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

Ответ 10

Если у вас несколько приложений, работающих в одной JVM.

Синглтон - это одноэлемент во всей JVM, а не только одно приложение. Даже если несколько потоков или приложений, похоже, создают новый одноэлементный объект, все они используют один и тот же, если они работают в одной JVM.

Ответ 11

В случае соединения (например), имеет смысл, что вы не хотите, чтобы соединение было одиночным, вам может понадобиться четыре подключения, или вам может понадобиться уничтожить и воссоздать соединение несколькими раз.

Но почему бы вам не получить доступ ко всем вашим соединениям через один интерфейс (т.е. диспетчер соединений)?