Наиболее распространенные примеры неправильного употребления singleton-класса

Я только что обнаружил, что мой код действительно работает. Проблема вызвана проблемой подключения к БД. БД не подключена должным образом, но AJAX все равно отвечает как «сделано».

12
задан Mark Biek 25 September 2008 в 19:18
поделиться

11 ответов

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

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

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

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

9
ответ дан 2 December 2019 в 06:28
поделиться

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

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

6
ответ дан 2 December 2019 в 06:28
поделиться

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

Так как исходный плакат хотел список случаев, когда Вы не должны использовать Одиночные элементы (а не главная причина), я соглашусь с:

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

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

3
ответ дан 2 December 2019 в 06:28
поделиться

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

2
ответ дан 2 December 2019 в 06:28
поделиться

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

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

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

1
ответ дан 2 December 2019 в 06:28
поделиться

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

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

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

2
ответ дан 2 December 2019 в 06:28
поделиться

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

IService service = IoC.GetImplementationOf<IService>();
1
ответ дан 2 December 2019 в 06:28
поделиться

Одна из вещей, которые имеют тенденцию делать это кошмаром, - то, если это содержит модифицируемое глобальное состояние. Я работал над проектом, где были Одиночные элементы, используемые повсеместно для вещей, которые должны были быть решены совершенно другим способом (передача в стратегиях и т.д.), "de-singletonification" был в некоторых случаях майором, переписывают частей системы. Я утверждал бы, что в большей части случаев, когда люди используют Singleton, это - просто неправильный b/c, это выглядит хорошим во-первых, но превращается в проблему особенно в тестировании.

0
ответ дан 2 December 2019 в 06:28
поделиться

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

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

0
ответ дан 2 December 2019 в 06:28
поделиться

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

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

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

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

Вы имели бы

Database ourDb;
Database otherDb;

чем копия - прошлая База данных и сделайте:

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

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

0
ответ дан 2 December 2019 в 06:28
поделиться

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

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

0
ответ дан 2 December 2019 в 06:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: