Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Singleton - зло?

505
15 января 2008 года
vAC
343 / / 28.02.2006
Несколько лет назад подрабатывал программистом в некоторой конторе. В одном из их проектов были обильно рассыпаны шаблоны-одиночки. Когда же я пришел за еще одной работой через годик, то в соглашении увидел выделяющееся требование - использование шаблона Singleton - категорически не допускается. Толи они наткнулись на проблемы с ними в том проекте, толи проектировщиков других взяли.
Сам обильно их не использовал, на памяти только один раз - и тот чисто для практики. Проект расширять не пришлось, поэтому проблем и не было. А вообще, я сам отрицательно отношусь к сему шаблону и хотелось бы узнать чужое мнение и опыт по этому вопросу...

p.s. недавно на этом форуме Green написал статейку по тому как с ними бороться
Страницы:
260
15 января 2008 года
Ramon
1.1K / / 16.08.2003
Все паттерны - Зло. :D
505
15 января 2008 года
vAC
343 / / 28.02.2006
опаньки :) это интересно
почему вы так считаете?
337
15 января 2008 года
shine
719 / / 09.06.2006
Singleton - инструмент. Кто им пользуется, такой результат и получается.
3
15 января 2008 года
Green
4.8K / / 20.01.2000
Синглтон - это глобальный объект, а любой глобальный объект - это как забитый гвоздь в растущую систему.
Может, повезет и система не будет нуждаться в расширении в этом направлении, а может не повезти... :)

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

Можно обеспечить существование единственного экземпляра и другими, менее жестокими способами, например, с помощью фабрики объектов. Синглтон содержит в себе фабрику единственного экземпляра, а так получается, мы выворачиваем синглтон наизнанку: теперь фабрика содержит экземпляр, а уж единственный он или нет - ей решать.
Это (IMHO) более гибкий способ, т.к. в зависимости от ситуации и с развитием системы, фабрика может создавать или не создавать новые экземпляры, а кроме того исключается "глобализация", система теперь "не знает" с единственным она работает экземпляром или нет, этим заведует лишь фабрика.

Резюме:
1) при развитии системы с синглтонами могут возникнуть проблемы,
2) без синглтонов можно обойтись, заменив их другим решением (фабрика)
Вывод: синглтоны - скорее зло, чем добро.
505
15 января 2008 года
vAC
343 / / 28.02.2006
Вспомнил свои мотивы использования этого шаблона:
Сначала решил, что класс действительно может иметь единственный экземпляр, но не это меня сподвигнуло на его использование, а банальная лень передачи указателя/ссылки :) и использование глобальных переменных - далеко не мудрое решение
276
16 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Green
Можно обеспечить существование единственного экземпляра и другими, менее жестокими способами, например, с помощью фабрики объектов. Синглтон содержит в себе фабрику единственного экземпляра, а так получается, мы выворачиваем синглтон наизнанку: теперь фабрика содержит экземпляр, а уж единственный он или нет - ей решать.
Это (IMHO) более гибкий способ, т.к. в зависимости от ситуации и с развитием системы, фабрика может создавать или не создавать новые экземпляры,


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

ЗЫ. Еще один вопрос родился.

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

361
16 января 2008 года
Odissey_
661 / / 19.09.2006
Цитата: shine
Singleton - инструмент. Кто им пользуется, такой результат и получается.


.....
[QUOTE=Эдсгер Дейкстра;]Инструменты, которые мы применяем, оказывают глубокое (и тонкое) влияние на наши способы мышления и следовательно на нашу способность мыслить. [/QUOTE]

3
16 января 2008 года
Green
4.8K / / 20.01.2000
Цитата: Rebbit
Ето конечно более гибкий способ, но вот что меня интересует. Если система в начале думает что она одна и достает етот екземпляр (который деюре не синглетон но дефакто таки один) из фабрики то что есть фабрика ? Как она должна гарантировать то что наш екземпляр будет един на нашу немасштабированую систему без того же приема что и в синглетоне ?. Ну припустим ето нас не очень пока интересует. Варианты есть. Смасштабируем - поменяем фабрику.
Но я так полагаю что методу фабрики который возвращает екземпляр параметры не передаются ? ведь зачем они если мы понятия не имеем будет ли система масштабироваться.
Как фабрика без параметров узнает из какой смасштабированой системы (ну уже подсистемы) у нее екземпляр просят ?


Ты же сам ответил на свой вопрос:
"Варианты есть. Смасштабируем - поменяем фабрику."
Как вариант, введем параметр у фабрики.

Цитата: Rebbit

ЗЫ. Еще один вопрос родился.

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


Интересные у вас заказчики, говорят использовать или нет синглтоны и т.п. :D
Заказчик обычно говорит: "хочу красиво", а что там внутри его не интересует.
Заказчик обычно ищет, где выгоднее (обратите внимание: не "где дешевле", а "где выгоднее", разница существенная). Поэтому команда должна быть конкурентноспособной, а значит и её наработки, и стиль, и каждый программист в отдельности должны быть конкурентноспособными (эффективными).

На счет "сразу не продумали", цитирую:

Цитата: Green
Представьте себе систему состоящую из множества подсистем.
Т.к. вся система изначально могла в приложении существовать только в единственном экземпляре, то сама она и многие её подсистемы были сделаны синглтонами ("одиночками"), кроме того в системе существует множество глобальных объектов.
За время своего существования (около 10 лет) система обросла множеством таких подсистем и глобальных объектов. И вот в один прекрасный момент понадобилось создать несколько таких систем в одном приложении. Вот тогда и почувствовалось всё зло от глобальных данных и синглтонов.

Последовательный рефакторинг (избавление от "одиночества") всех подсистем оказался очень трудоемким, в частности из-за большой связанности подсистем: приходилось протаскивать ссылки на соседние подсистемы по всей иерархии вызовов и/или хранить множество перекрестных ссылок.



Сразу мучаться и не надо, отсюда и возникает вопрос: зло синглтоны или нет. Если сразу понимаешь, что зло, то стараешься избежать их использования, и не надо ничего предвидеть. Это и называется стиль, когда не "предвидишь" в данном конкретном случае, а пользуешься набором правил выработанных или приобретенных.
"Не совать пальцы в розетку", и не надо предвидеть есть там напряжение или нет.
"Не направлять оружие на людей", и не надо предвидеть будет оно заряжено или нет.

Цитата: Rebbit

Возможно я просто не понимаю как можно легко обойтись без синглетонов с помощю фабрик ?


Возможно. Но это лишь один из примеров.

276
16 января 2008 года
Rebbit
1.1K / / 01.08.2005
Ну то что синглетоны не очень хорошо ты меня убедил еще той темой где ты с ними боролся (хотя я особо не вникал изза своей же некомпетентности в том числе и в С++).
Но опять же если роботу отдать и забыть - то почему бы их не использовать. Конечно если проект серезный - ты 100% прав в том чтоб ими не пользоваться.
Но я бы избавлялся от них не с помощю фабрик. Не нравится мне такой выход. Если я планирую что система будет розвиватся и совсем непонятно как то я бы сделал саму систему сущностю.
Пусть она поддерживает некий интерфейс IRunable и все что в ней должно быть глобальным пускай содержится в етой сущности. Подсистемы етой системы, использующие глобальный ресурс (ну типа синглетоны, статические поля и прочие глобальные переменные) должны хранить ссилку на инстант нашей системы сущности, чтоб получить доступ к общему ресурсу.
Реально глобальной я би сделал только одну самую начальную сущность (к примеру клас со статическим методом, чтото типа public static main), которая будет запускать мою IRunable. Если придется масштабировать или достраивать поверха вверх - просто делаем новий IRunable верхнего уровня, который в себе уже запускает прежние IRunable в сколь-угодном количестве и переделываем наш клас со статической функцией который ету всю кухню запускает.
Конечно предложеную мною сущность системы можно асоциировать с фабрикой - но помоему ето разные вещи. Ето получится не фабрика, а держатель псеглобальных переменных. И не очень напряжет при розроботке первичной системы. Но ето только моя теория. Практически я таког не делал.

ЗЫ. не смотря на то что я сказал "синглетоны не очень хорошо" - проблема не в синглетоне, а в том что мы не можем нормально определится что должно быть глобально а что нет и тыкаем етот паттерн всюду где не надо. Так что я голосую за добро, но теперь буду с етим добром намного осторожнее. :)

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

ЗЫЫ. Подозреваю что хранение ссылок на инстанс системы-сущности может вызват неудобства при роботе сборщика мусора. Но таких проблем и без меня хватит. Я вообще не понимаю почему там где есть GC нельзя убить укземпляр руками. Но ето уже другая тема в которой я понятия не имею.

ЗЫЫЫ Еще не все сказал
Цитата:
Как вариант, введем параметр у фабрики.


Не нравится почемуто. Надстраивать понимаю, а перестраивать не люблю.

Цитата:
Интересные у вас заказчики, говорят использовать или нет синглтоны и т.п.


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

Цитата:
На счет "сразу не продумали", цитирую:


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

3
17 января 2008 года
Green
4.8K / / 20.01.2000
Цитата: Rebbit

Но опять же если роботу отдать и забыть - то почему бы их не использовать.


Профессиональные разработчики имеют обыкновение использовать свой код неоднократно.

Цитата: Rebbit

Но я бы избавлялся от них не с помощю фабрик. Не нравится мне такой выход. Если я планирую что система будет розвиватся и совсем непонятно как то я бы сделал саму систему сущностю.
Пусть она поддерживает некий интерфейс IRunable и все что в ней должно быть глобальным пускай содержится в етой сущности. Подсистемы етой системы, использующие глобальный ресурс (ну типа синглетоны, статические поля и прочие глобальные переменные) должны хранить ссилку на инстант нашей системы сущности, чтоб получить доступ к общему ресурсу.
Реально глобальной я би сделал только одну самую начальную сущность (к примеру клас со статическим методом, чтото типа public static main), которая будет запускать мою IRunable. Если придется масштабировать или достраивать поверха вверх - просто делаем новий IRunable верхнего уровня, который в себе уже запускает прежние IRunable в сколь-угодном количестве и переделываем наш клас со статической функцией который ету всю кухню запускает.
Конечно предложеную мною сущность системы можно асоциировать с фабрикой - но помоему ето разные вещи. Ето получится не фабрика, а держатель псеглобальных переменных. И не очень напряжет при розроботке первичной системы. Но ето только моя теория. Практически я таког не делал.


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

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

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

3. Большие структуры не наглядны. Они сложны для понимания, а в большой команде или при продолжительной жизни кода, сам черт ногу сломит что в ней надо, а что нет, что к чему относится. А рефакторить такие объемы тяжело. Короче само по себе это противоречит методике "разделяй и влавствуй".

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

Цитата: Rebbit

ЗЫ. не смотря на то что я сказал "синглетоны не очень хорошо" - проблема не в синглетоне, а в том что мы не можем нормально определится что должно быть глобально а что нет и тыкаем етот паттерн всюду где не надо. Так что я голосую за добро, но теперь буду с етим добром намного осторожнее. :)


Так держать! :)
В идеале в программе должна быть одна единственная глобальная вещь - точка входа. :)

Цитата: Rebbit

Не нравится почемуто. Надстраивать понимаю, а перестраивать не люблю.


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

Цитата: Rebbit

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


Взаимоотношения между заказчиком и исполнителем значительно сложнее, чем "пускай платит, а фирма будет рефакторить". В реальном мире правят заказчики.

276
17 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Green

В идеале надо сразу инициировать весь контекст и единовременно его уничтожать.


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

Цитата: Green

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


Ето придется делать для всего сложнее "Hello world"

Цитата: Green

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

Взаимоотношения между заказчиком и исполнителем значительно сложнее, чем "пускай платит, а фирма будет рефакторить". В реальном мире правят заказчики.


Всему етому охотно поверю.

А вообще под термином "надстраивание" я имел ввиду не рефакторинг, а возможность использование уже готовой системы А (ту что мы сейчас делаем) как подсистемы чегото большего (надсистемы Б в которой подсистема А может присутствовать в нескольких екземплярах) и чтоб ето все с мимнимумом усилий по стыковке.

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

Цитата: Green

Так держать! :)


Ето стеб ? :)

Цитата: Green

В идеале в программе должна быть одна единственная глобальная вещь - точка входа. :)


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

3
17 января 2008 года
Green
4.8K / / 20.01.2000
Кстати, голосование какое-то необоснованное идет.
В данном случае, я противник тайного голосования.
Объясняйте хоть, на чем основываясь отдаете предпочтение в голосе.
Причем, "зло" - я примерно представляю кто и по каким причинам выбрал.
А вот, "добро" объяснил пока только Rebbit.
3
17 января 2008 года
Green
4.8K / / 20.01.2000
Цитата: Rebbit

[quote=Green;230238]
Получается надо вводить какие-то доп. механизмы, чтоб определять состояние самого контекста.


Ето придется делать для всего сложнее "Hello world"
[/QUOTE]
В том то и дело, что НЕТ.
Нужны данные, - они создаются. Не нужны - их просто нет.

Цитата: Rebbit

Ето стеб ? :)


Нет, это одобрение, подбадривание...

Цитата: Rebbit

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


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

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

241
29 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Добро, если это решение должно быть обосновано и документировано.

P.S. Что характерно: в этом опросе зло - безоговорочно, а вот добро - с оговорками.:)
3
29 января 2008 года
Green
4.8K / / 20.01.2000
Цитата: Sanila_san
Добро, если это решение должно быть обосновано и документировано.


Любое решение должно быть обосновано и, желательно, задокументировано. Код - это, кстати, тоже документ. :)
Ну это так... лирика...

255
29 января 2008 года
Dart Bobr
1.4K / / 09.04.2004
По-моему опрос все-таки не уместен. Как вариант можно так-же спросить: "молоток - это добро или зло?" Аргументы есть как за - "классно гвозди вбивает", так и против - "если промахнуться и по пальцу ударить - больно".
3
29 января 2008 года
Green
4.8K / / 20.01.2000
Опрос существует не в воздухе, топик дает представление о контексте - хороший стиль программирования.
Используя твою метафору с молотком можно задать контекст:
"Молоток при настройке телевизора - это добро или зло?"
255
30 января 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Green
Опрос существует не в воздухе, топик дает представление о контексте - хороший стиль программирования.
Используя твою метафору с молотком можно задать контекст:
"Молоток при настройке телевизора - это добро или зло?"



Ну, опрос же не звучит как "Синглтон при моделировании моделек человечков на 3D Studio Max - добро или зло". Поутрируя можно так же спросить "массив - это добро или зло". Это всего-лишь инструмент.

241
30 января 2008 года
Sanila_san
1.6K / / 07.06.2005
[QUOTE=Green;231768=Green;231768]Любое решение должно быть обосновано и, желательно, задокументировано. Код - это, кстати, тоже документ. :)
Ну это так... лирика...[/QUOTE]Ну, я с синглтонами не сталкиваюсь практически, поэтому выдал хоть и своё мнение, но, скажем так, не особо практическое, тогда как критерий истины именно практика. Насколько я понял из обсуждения, синглтон - не зло, но опасная практика. Поэтому проголосовал за добро, ибо опасная практика - не всегда плохая.

Зло в моём понимании - это
 
Код:
define begin {
define end }
а ещё код без комментариев и глобальные переменные. Остальное, по-моему, всё же вещи либо опасные, либо необоснованные, либо и то, и другое.

Цитата: Green
Опрос существует не в воздухе, топик дает представление о контексте - хороший стиль программирования.
Используя твою метафору с молотком можно задать контекст:
"Молоток при настройке телевизора - это добро или зло?"

В контексте топика синглтон - зло, и опрос, собственно, не нужен, поскольку его использование уже запрещено. :) А вне контекста решения конкретных разработчиков это всего лишь опасная практика.

505
30 января 2008 года
vAC
343 / / 28.02.2006
Цитата: Sanila_san
Ну, я с синглтонами не сталкиваюсь практически, поэтому выдал хоть и своё мнение, но, скажем так, не особо практическое, тогда как критерий истины именно практика. Насколько я понял из обсуждения, синглтон - не зло, но опасная практика. Поэтому проголосовал за добро, ибо опасная практика - не всегда плохая.

Зло в моём понимании - это
 
Код:
define begin {
define end }
а ещё код без комментариев и глобальные переменные. Остальное, по-моему, всё же вещи либо опасные, либо необоснованные, либо и то, и другое.


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

А по какому критерию вы относите глобальные переменные ко злу?

3
30 января 2008 года
Green
4.8K / / 20.01.2000
Цитата: Dart Bobr
Ну, опрос же не звучит как "Синглтон при моделировании моделек человечков на 3D Studio Max - добро или зло". Поутрируя можно так же спросить "массив - это добро или зло". Это всего-лишь инструмент.



Цитата: Green
Опрос существует не в воздухе, топик дает представление о контексте - хороший стиль программирования.



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

Другими словами, я рассказал, что бывает плохого, если употреблять синглтоны, и как без них обойтись.
Расскажите мне о том, когда без них не обойтись и какие безоговорочные плюсы по сравнению с др. вариантами мы имеем. Не надо мне доказывать, что такие ситуации бывают, просто, покажите конкретные примеры, когда они случаются. Тогда то мы и сможем определиться, в каких случаях этот инструмент стоит применять (и только его) и что случится, если его не применить.

"Это всего-лишь инструмент" - слишком расплывчато, чтоб быть аргументом. Стоп-кран - тоже "всего-лишь инструмент".

Могу согласиться с такой формулировкой: "Это всего-лишь инструмент, которым лучше не пользоваться без КРАЙНЕЙ необходимости", а т.к. настоящие крайности случаются редко (опытный разработчик, просто, не допускает появления крайностей), то лучше вообще не пользоваться.

505
30 января 2008 года
vAC
343 / / 28.02.2006
Ради интереса откопал исходники того самого проекта, который упоминал в первом посте. На тот момент в нем содержалось 33 синглетона :) Такое впечатление, что архитектор либо отрабатывал на практике этот шаблон проектирования, либо не хотелось определять связи между сущностями. Практически все стоит на нем: визуализация и работа с данными документа (пригвоздили всю архитектуру doc/view), работа с буффером обмена, графическая подсистема, всевозможные преобразования объектов, обработка нажатия клавиш...

Думаю это было сделано от лени или поджимающих сроков, либо привлекло то, что из любого места программы можно без особых затруднений получить доступ ко всему и сразу.
241
31 января 2008 года
Sanila_san
1.6K / / 07.06.2005
Цитата: vAC
А по какому критерию вы относите глобальные переменные ко злу?

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

255
31 января 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Green
Кроме того мой голос я детально прокомментировал с примерами и альтернативой использованию синглетона, о чем и других просил.
К сожалению, не увидел ничего подобного для варианта "добро".

Другими словами, я рассказал, что бывает плохого, если употреблять синглтоны, и как без них обойтись.
Расскажите мне о том, когда без них не обойтись и какие безоговорочные плюсы по сравнению с др. вариантами мы имеем. Не надо мне доказывать, что такие ситуации бывают, просто, покажите конкретные примеры, когда они случаются. Тогда то мы и сможем определиться, в каких случаях этот инструмент стоит применять (и только его) и что случится, если его не применить.

"Это всего-лишь инструмент" - слишком расплывчато, чтоб быть аргументом. Стоп-кран - тоже "всего-лишь инструмент".

Могу согласиться с такой формулировкой: "Это всего-лишь инструмент, которым лучше не пользоваться без КРАЙНЕЙ необходимости", а т.к. настоящие крайности случаются редко (опытный разработчик, просто, не допускает появления крайностей), то лучше вообще не пользоваться.



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

276
31 января 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Dart Bobr
Ну например.. если объект работает с каким-либо ресурсом, который невозможно залочить.


Ну как по мне вот тут синглетон вообще ни при чем. Я бы тут точно фабрикой делал. Получаю идентификатор ресурса - отдаю обект для роботы с ним. А синглетон тут не поможет при защите от "дурака". Что мешает обращаться к ресурсу без синглетона-врапера ?

505
31 января 2008 года
vAC
343 / / 28.02.2006
Предлагаю сформировать сводную таблицу плюсов и минусов, и тогда, возможно, придем к какой-то резолюции.
плюсы
...
минусы
1. глобализация сущностей => перекрывает пути к расширению;
2. сложности использования шаблона в динамических библиотеках.

по второму пункту ситуация может возникнуть следующая:
в каждой из нескольких библиотек используется шаблон-синглетон, при подключении их к программе, получим несколько экземпляров, что не отвечает требованиям самого шаблона.
63
31 января 2008 года
Zorkus
2.6K / / 04.11.2006
Цитата: vAC

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


Это что - к программе подключать несколько копий одной и той же библиотеки? Иначе откуда несколько копий одинаковых объектов?

505
31 января 2008 года
vAC
343 / / 28.02.2006
Нет, библиотеки разные, и создаются не копии одинаковых (я этого не говорил) объектов, а новые экземпляры, например, путем подключения какой-нибудь общей для них статической библиотеки, где и определен шаблон.
255
01 февраля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Rebbit
Ну как по мне вот тут синглетон вообще ни при чем. Я бы тут точно фабрикой делал. Получаю идентификатор ресурса - отдаю обект для роботы с ним. А синглетон тут не поможет при защите от "дурака". Что мешает обращаться к ресурсу без синглетона-врапера ?


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

3
01 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Dart Bobr
Тогда, как сказал выше Ramon - все паттерны зло. Ведь без любого из них можно спокойно обойтись.


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

Цитата: Dart Bobr

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


Какой аргумент? "Не обойтись"? Так я привел несколько аргументов, это ты прицепился лишь к одному, причем в его полярном варианте. Ещё раз обрати внимание на мой предыдущий пост. Из него можно выделить следущие полярности:
"что бывает плохого" - "безоговорочные плюсы"
"как обойтись" - "когда не обойтись"

Цитата: Dart Bobr

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


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

255
01 февраля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Хорошо, давай абстрагируемся от понятий паттернов. Синглтон являет собой некоторую сущность, как и любой другой объект(класс, структура, переменная, неважно). Ты утверждаешь, что фактически нет сущностей, которые существуют в одном экземпляре(так как нам может понадобиться создать две или больше таких сущностей при масштабировании системы), и ты предлагаешь использовать другую сущность(фабрику) для контроля первой сущности, и создавать каждую в своем контексте. То-есть в своей "области видимости" первая сущность останется синглтоном. Грубо говоря у нас появляется n сущностей, каждая из которых не знает про сущевствование остальных. Но, каждая из них остается именно такой(синглтоном). Следовательно ты не "борешься" с синглтоном, а просто уменьшаешь его область видимости, но сама сущность синглтона так и остается.

Вернемся к нашим баранам(синглтонам) :)
Теперь представим другой вариант. У меня есть фабрика. Причем при инициализации фабрики должен обязательно инициализироваться экземпляр сущности синглтона(что-то вроди статического члена). Тогда создав еще один экземпляр фабрики, я все равно столкнусь с проблемами, если этот "статический" синглтон работает с каким-либо важным незалоченым ресурсом. Тогда получается, что наша фабрика, как сущность, должна быть синглтоном, в классическом понимании этого слова..
505
01 февраля 2008 года
vAC
343 / / 28.02.2006
Цитата: Dart Bobr
Грубо говоря у нас появляется n сущностей, каждая из которых не знает про сущевствование остальных. Но, каждая из них остается именно такой(синглтоном).


Ну, например, множество векторов тоже не знают друг о друге, тем не менее синглетонами их не называют

Цитата: Dart Bobr
У меня есть фабрика. Причем при инициализации фабрики должен обязательно инициализироваться экземпляр сущности синглтона(что-то вроди статического члена).



Вовсе не обязательно

3
01 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: Dart Bobr
Хорошо, давай абстрагируемся от понятий паттернов.


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

Цитата: Dart Bobr

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


Нет, такие сущности не будут синглтонами по определению:

Цитата:

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


Теперь гарантирует не сам объект, а фабрика его породившая.
Сам же объект перестает быть синглтоном.

Цитата: Dart Bobr

Вернемся к нашим баранам(синглтонам) :)
Теперь представим другой вариант. У меня есть фабрика. Причем при инициализации фабрики должен обязательно инициализироваться экземпляр сущности синглтона(что-то вроди статического члена).


Почему, "должен обязательно"?
Здесь могут быть совершенно различные механизмы.

Цитата: Dart Bobr

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


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

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

255
04 февраля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Ладно. Приведу пример, так как не все до конца поняли что я имею в виду. Пусть нами разрабатывается мир для RPG(который расширяется с 1 планеты до многих, в ходе разработки). Пусть есть класс:
 
Код:
class СPlanet
{
}

Для нее пусть проектируется класс Солнце, причем для конкретной планеты - есть только одно Солнце
 
Код:
class СSun
{
}

При создании экземпляра класса планеты - автоматически создается экземпляр Солнца. Поскольку по задумке для планеты существует одно солнце, то логично его сделать Синглтоном(пока не назрела идея расширить мир до двух и больше планет).. При расширении мира - нам удобно сделать фабрику - контролирующую производство наших Синглтонов(солнц), с методом CreateSun, создающим конкретный экземпляр Солнца, для планеты:
 
Код:
class CSunFabric
{
public:
  ID CreateSun(...);
}

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

Что я хочу этим сказать - что от синглтона невозможно избавиться. Всегда может оказаться, что при расширении системы некоторые объекты - нужно сделать синглтонами, но при последующем расширении, они уже таковыми быть не должны. Поэтому, я например не согласен с высказыванием Green'а, что
Цитата:
в идеале в программе должна быть одна глобальная вешь - точка входа

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

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

276
04 февраля 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: Dart Bobr
При создании экземпляра класса планеты - автоматически создается экземпляр Солнца.


ЗАЧЕМ ???? :eek: Если у планеты может быть только одно солце (не 0 и не больше) то совсем не обязательно создавать солнце при создании планеты. На мой взгляд ето плохо. В планете нужно сделать поле ссылающееся на ее солнце (ето и так ясно) а для того чтоб не допустить создание планеты без солца нужно передавать солце конструктору планеты и уже в конструкторе проверять чтоб не передали NULL.

505
04 февраля 2008 года
vAC
343 / / 28.02.2006
Да, здесь пожалуй надо архитектуру переработать...
Получается, что планета имеет связь типа has с Солнцем...и что получается: значит бомбим планету, а за ней и вся солнечная система гибнет? :)

Логичнее было бы иметь агрегацию планет в солнечной системе.

Можно сделать фабрику солнечных систем, а каждый продукт этой фабрики предоставляет абстрактную фабрику планет. Это дает много возможностей. Например, в зависимости от солнечной системы предоставлять разные фабрики планет. При этом клиент даже не будет подозревать о замене, и весь код по созданию планет останеться неизменным.
Ну а при уничтожении Солнца, логично уничтожить и все вокруг.
3
04 февраля 2008 года
Green
4.8K / / 20.01.2000
Dart Bobr, ты в своем примере даже не попытался отойти от синглтона. В упрощенном виде ты пытаешься сделать следущее:
 
Код:
void Subsystem::func()
{
   Singleton::getInstance().callMethod();
}

заменяешь на
 
Код:
void Subsystem::func()
{
   ::createObject().callMethod();
}

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

Я же предлагаю следущее:
 
Код:
Subsystem::Subsystem(object)
: _object(object)
{}

void Subsystem::func()
{
   _object.callMethod();
}

или так
 
Код:
void Subsystem::func()
{
   ::createObject(systemID).callMethod();
}

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

Собственно Rebbit тебе и предложил более аккуратное архитектурное решение, которое соотв. первому варианту кода.
276
04 февраля 2008 года
Rebbit
1.1K / / 01.08.2005
Цитата: vAC

Получается, что планета имеет связь типа has с Солнцем...и что получается: значит бомбим планету, а за ней и вся солнечная система гибнет?


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

Сори за лирическое отступление.

505
04 февраля 2008 года
vAC
343 / / 28.02.2006
Сорри, не вставил цитату. Это был ответ на пост Dart Bobr :)
Все правильно, связь планеты и звезды - "use". Еще добавлю, что для этого примера использование синглетона никаких плюсов не дает. Даже если создать несколько фабрик звездных систем, то ничего страшного не поризойдет, даже наоборот. Сможем одновременно иметь несколько моделей Вселенной :)
з.ы. сказался школьный пробел в астрономии. Имелось ввиду конечно не "солнечная система", а "звездная система". Кстати бывают звездные системы, состоящие из двух и более звезд...:)
255
04 февраля 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: Green

Я же предлагаю следущее:
 
Код:
Subsystem::Subsystem(object)
: _object(object)
{}

void Subsystem::func()
{
   _object.callMethod();
}



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

 
Код:
void SubSystem::func1()
{
  this->func();
  Subsystem * temp = new SubSystem();
  temp->func();
}

Теперь я могу к одной планете "насильно" привязать второе Солнце...

2 Rebbit
Я не уверен, что передача в конструктор критичных параметров является хорошей идеей. Вот например передам я созданой планете NULL вместо солнца. И что тогда? Использовать прямо в конструкторе сомнительный код вроде:
 
Код:
delete this;

?? Просто, насколько я себе представляю - передача в конструторе критичных параметров - передает управление объектом самому объекту, а это не есть хорошо.

Знаете кого-то, кто может ответить? Поделитесь с ним ссылкой.

Ваш ответ

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог