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

Синглтоны действительно так плохо?

Возможный дубликат:
Что плохого в синглтонах?

Понятно, что многие шаблоны дизайна могут в некоторых случаях подвергаться насилию, и, как всегда, мама всегда говорила: "Слишком много хорошего не всегда хорошо!"

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

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

Эти данные централизованы с помощью класса Singleton, который объединяет несколько объектов ArrayCollections, Arrays, value и некоторые другие собственные переменные-члены, открытые через getters и seters.

Чтобы получить ссылку на наши данные из любого места приложения, мы делаем весь метод метода Model.getInstance(), и я уверен, что все знакомы. Это гарантирует, что мы всегда получаем одну и ту же копию данных, так как при проектировании мы говорили, что только один экземпляр разрешен для существования в течение срока службы приложения.

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

До сих пор этот подход был эффективен и оказался очень практичным для наших обстоятельств.

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

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

Кроме того, может ли кто-нибудь рекомендовать хорошую книгу по шаблонам дизайна?

4b9b3361

Ответ 1

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

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

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

Учитывая, что вы говорите: "Этот подход был эффективен и оказался очень практичным для наших обстоятельств", я думаю, вы все в порядке.

Вот несколько хороших книг:

Книга "Банда четырех" - классическая книга для шаблонов дизайна

Head First Design Patterns - Я слышал, что это рекомендовано несколькими людьми в качестве альтернативы

Ответ 2

Да, синглтоны плохие. Они плохи, потому что все, что они делают для вас, объединяют два свойства, каждый из которых плох примерно в 95% случаев. (Что означало бы, что в среднем одиночные числа плохие 99,75% времени;))

Синтаксис, определяемый GoF, представляет собой структуру данных, которая:

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

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

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

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

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

Они делают его чрезвычайно трудным для модульного тестирования. (Как вы проверяете функцию, которая вызывает функции на объекте singleton? Мы не хотим, чтобы фактический одноэлементный код выполнялся, но как это предотвратить?

Да, синглтоны плохие.

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

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

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

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

Ответ 3

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

  • Идеалистический: никогда не используйте одноэлементный шаблон.
  • Прагматический: избегайте одноэлементного шаблона.

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

  • Является ли singleton внешним для вашего приложения? Базы данных, службы очередей и ESB - все это вполне допустимые примеры макросов одноэлементного шаблона.
  • KISS: все ли ваше приложение ограничено 2-3 внутренними синглонами?
  • СУХОЙ: Являются ли эти синглтоны по своей сути глобальными и поэтому должны были бы отбрасывать ссылки почти на каждый объект вашего приложения? (например, регистратор или компонентный посредник)?
  • Влияют ли ваши синглеты друг на друга и/или операционная среда?
  • Были ли вы обеспечены правильные последовательности запуска и выключения для каждого синглтона, включая соображения управления памятью? Например, пул потоков "Grand Central" может нуждаться в методах экземпляра Run() и Shutdown() в main(), чтобы гарантировать выполнение задач только тогда, когда объекты, в которых они работают, находятся в допустимом состоянии.

Ответ 4

Синглеты не убивают программы, программисты убивают программы.

Как и любая конструкция программирования, при правильном использовании вы не будете стрелять в ногу.

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

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

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

Ответ 5

Мы начали проект, в котором мы в основном сталкиваемся с тем же вопросом, то есть, как получить доступ к модели и особенно к ее корневому элементу. Проект - это не приложение Flex, а игра! веб-приложение, но это не имеет никакого значения.

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

Основными аргументами для DI являются следующие:

  • проверяемость и насмешка
  • отключение объекта от использования (что может привести к управлению жизненным циклом)
  • разделение проблем

Возможные подходы к DI (см. классический article от Fowler):

  • передать объект в параметрах метода
  • локатор сервисов
  • Структура DI

В этой перспективе одноэлементный шаблон является всего лишь своего рода локатором сервисов, например. Model.getInstance().

Но для обеспечения максимальной гибкости перед будущими изменениями ссылка на уникальный объект должна быть передана как можно больше и получена с помощью Model.getInstance() только при необходимости. Это также даст более чистый код.

Ответ 6

По моему мнению, использование синглтонов напрямую сигнализирует о дефекте дизайна. Причина в том, что они позволяют обойти механизмы создания и уничтожения обычных объектов, встроенные в С++. Если объекту нужна ссылка на другой объект, он должен либо передать ссылку на него при построении, либо создать новый экземпляр внутри него. Но когда вы используете синглтон, вы явно запутываете цикл создания и разрыва. Связанная с этим проблема заключается в том, что чрезвычайно сложно контролировать время жизни одноэлементного. В результате многие пакеты, которые включают в себя общие реализации singleton, также включают в себя неуклюжих менеджеров жизни объекта и т.п. Иногда я задаюсь вопросом, существуют ли они просто для управления одиночными играми.

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

Ответ 7

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

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

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

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

Вся суть синглтона заключается в том, что он для объектов, где только один должен существовать. Вы упомянули набор классов управления данными. Возможно, подумайте, что на самом деле есть случаи, когда приложение может захотеть создать 2 набора классов управления данными, поэтому, возможно, применение синглтона на этом не совсем правильно. Вместо этого, если вы создали эти классы данных в приложении init и передали их, вы бы только создали 1 набор, поскольку это то, что вам требуется в текущем приложении, но вы оставляете открытым возможность, что в какой-то момент, если вам нужен второй набор вы можете легко их создать. Кроме того, если классы управления данными действительно доступны глобально из любого места приложения. Я думаю, что нет, вместо этого они должны быть доступны только с уровня доступа на более низком уровне.

Некоторые люди рекомендовали книгу GOF. Я бы сказал, да, это отличная книга, но сначала попробуйте сначала найти книгу об общей архитектуре, сначала прочитайте о дизайне 2/3/n-уровня, инкапсуляции, абстракции и этих принципах. Это даст вам более прочную основу для понимания правильного использования шаблонов, о которых говорит GOF.

[Edit: другое время, когда одноэлементный вариант может быть полезным, - это когда вы хотите, чтобы одна точка доступа была чем-то, но деталь реализации может быть более чем одной. Вызывающему не нужно знать, что под обложками их запрос для объекта singleton фактически разрешен против нескольких доступных объектов, и один возвращается. Я думаю о чем-то вроде пула потоков здесь, где использование идет, эй, просто дай мне поток, мне нужно 1, но мне все равно, какой из них]

Ответ 8

Я знаю, что это старый поток, но никто, похоже, не упомянул фактический шаблон, который соответствует тому, что пытался сделать OP. Я полагаю, что он описывает необходимость, называется "Посредник" . SourceMaking - это фантастический сайт для обучения/ссылки на этот вид информации. Определенно, я собираюсь разместить людей для разработки программ. Кроме того, это вообще хорошая идея не покупать в понятии, что любой шаблон дизайна обязательно является по своей сути хорошим или злым. Они все используют, они только учатся, когда и где их использовать, что является трюком. Люди, которые заявляют, что никогда не используют Синглтонов, не понимают их полезности.

Ответ 9

Нет, они не обязательно плохие.

Что касается книги, вам нужно начать с классики.

Ответ 10

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

Что касается книг, ну, вот какой-то канон.

Ответ 12

Google кажется убежден, что Singletons - плохая идея.

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