Просмотр полной версии : Одиночка: частота применения
Хотелось бы узнать как часто вы используете паттерн Singleton. И в каких случаях. Вопрос навеян впечатлением, что я его использую слишком часто. Интересно услышать ваше мнение по этому поводу, поделитесь опытом.
Недавно в блогах была статья и обсуждение http://www.flasher.ru/forum/blog.php?b=286
udaaff, да, я читал это. Вопрос немного в другом. В том числе в статистике.
Вот у меня есть проект, там в качестве одиночек выступают классы, которые:
1) Управление хранением ряда данных (игровые очки, битмапы и т.п.)
2) Управление таймером
3) Управление SharedObject
4) Управление звуками (при чем данный класс можно разделить на 2, т.к. звуки отдельно управляются в зависимости, являются ли они эффектами или просто фоновой музычкой)
5) Обмен данными с серваком
6) Глобальный трэйсер (спрайт, который добавляется в самом начале, содержит текстовое поле, куда можно писать логи, которые можно (проще) отследить только при работе приложения с сайта)
7) Управление настройками
8) ...? возможны еще варианты
Меня лично такое количество одиночек начинает пугать. Вот я и задумался об адекватности такой структуры. С одной стороны да, все эти классы должны быть в единственном экземпляре, т.е. то самое основное предназначение одиночки. С другой - становится страшно от такого изобилия.
Как вариант сделать одиночку, который бы содержал в себе все эти классы и доступ был бы типа такого:
var timeManager:TimeManager=Singleton.getInstance("название_нужного_класса");
Да, я знаю, что тема замызгана до смешного, но хотелось бы для себя разобраться, все ли я правильно делаю.
JackFromChaos
31.12.2010, 15:42
Ну, имхо, единая точка для разных сингелтонов лучше не сделает... Только усложнит синтаксис, и вероятность возникновении ошибки при написании "название_нужного_класса".
Предпочитаю код аля:
LocalizeString.instance.getString(code);
Вообще не вижу тут проблем, у меня самого похожий набор синглтонов, причем большая часть из них яляеются библиотечными классами, мигрирующими из проекта в проект без изменений.
К твоему списку могу добавить систему локализации.
Если мне не изменяет память, то я ни разу им не пользовался, ыы. Вообще недолюбливаю статичные методы и переменные.
Разве что глобальный трейсер-логгер, который уже давно написан, но как бы и он без использования синглтона... зачем?
Bgg, ну из статичных там получается только одна булевая переменная на один класс, т.е. отрицательнре влияние статики стремиться к нулю.
И если ими не пользуешься, то как выходишь из ситуации? Вот к примеру ситуация: настройки звука хранятся в абсолютно разных местах, в абсолютно разных классах (я на своей памяти таких мест более 2х не встречал, но теоретически их может быть и больше, т.к. настройки звука - только в качестве примера) Как бы реализовал это без одиночки?
JackFromChaos, ошибки не будет, т.к. "название_нужного_класса" будет выноситься в статические переменные. А по коду немного не понял что к чему.
Я пользуюсь синглтонами довольно редко. Я нашел их применение в качестве интерфейса к заведомо единственным сущностям, таким как звук, клавиатура или SharedObject.
Делать синглтоном класс для работы с сервером, скажем, не вижу особого смысла: вдруг приложению понадобится работать с несколькими разными серверами? :) Даже если не понадобится, при создании еще одного экземпляра такого класса ничего не сломается, конфликтов не возникнет - все по-прежнему будут пользоваться ссылкой на нужный экземпляр.
Зачем вообще может понадобиться синглтон? Мне кажется, основная причина - его глобальная доступность. Здесь я предпочитаю выбрать инкапсуляцию: те, кому объект нужен, получат на него ссылку, а остальные пускай не суются.
В общем, моя философия такая: без необходимости синглтоны не делать, ибо результат получится тот же, а разводить архитектуру ради архитектуры - лишняя трата времени.
Bgg, ну из статичных там получается только одна булевая переменная на один класс, т.е. отрицательнре влияние статики стремиться к нулю.
И если ими не пользуешься, то как выходишь из ситуации? Вот к примеру ситуация: настройки звука хранятся в абсолютно разных местах, в абсолютно разных классах (я на своей памяти таких мест более 2х не встречал, но теоретически их может быть и больше, т.к. настройки звука - только в качестве примера) Как бы реализовал это без одиночки?
Что за настройки? Громкость что ли? Ссылками на звуковой контроллер у которого будет геттер громкости. Вообще как то не правильно... почему Настройки звука хранятся в разных классах?
Если ты про проигрывание звука, то пользовался бы событиями: звуковой контроллер находится в главном контроллере и слушает определенные типы событий, и на основе типа события или event.target'а воспроизводит тот или иной звук. Так же и события выключения звука, громкости и прочих настроек.
terbooter
31.12.2010, 20:06
Если на собеседовании претендент утверждает, что знает шаблоны и из всего списка имеющихся приводит только синглтон, то это значит что он их не знает вовсе =)
У синглтона плюсы небольшие, но минусы огромные.
Лично я стараюсь не использовать.
GAIKER, сервер - да, просто задача немного специфическая.
Мне кажется, основная причина - его глобальная доступность.
В том-то и проблема, что основной причиной должна быть
заведомо единственным сущностям
Здесь я предпочитаю выбрать инкапсуляцию: те, кому объект нужен, получат на него ссылку, а остальные пускай не суются.
Я бы тоже предпочел такой вариант, но у меня скорее не хватает опыта, чтоб максимально избавиться от одиночек в пользу инкапсуляции.
В общем, моя философия такая: без необходимости синглтоны не делать, ибо результат получится тот же, а разводить архитектуру ради архитектуры - лишняя трата времени.
Абсолютно согласен, но очень сильно сомневаюсь, что у меня правильный подход для реализации этой философии
Bgg, громкость-то настраивается в одном классе, а результаты настроек отображаются в нескольких.
Bgg, громкость-то настраивается в одном классе, а результаты настроек отображаются в нескольких.
Почитай тему про MVC. Как только контроллер звука изменил громкость он шлет событие об этом, и те объекты кого это интересует должны это событие услышать.
terbooter
31.12.2010, 20:22
Вообщем, синглтон в неумелых руках это зло.
Тк бесконтрольное его применение позволяет разводить макаронный код, при этом автор утверждает, что ничего страшного, он же использует шаблоны =)
terbooter
У синглтона плюсы небольшие, но минусы огромные.
можно про минусы подробней? Согласен что они есть, но вот в чем "огромногсть"?
Лично я стараюсь не использовать.
Каким образом удается обходиться без одиночки?
при этом автор утверждает, что ничего страшного, он же использует шаблоны =)
Я ничего не утверждаю, я чувствую недостатки в своей манере программирования и хочу исправить ситуацию.
Каким образом удается обходиться без одиночки?
А каким образом устроен ваш код, что необходимо наличие одиночки? Что в нем сломается, если одиночку превратить в обычный класс?
mikhailk
02.01.2011, 01:17
можно про минусы подробней? Согласен что они есть, но вот в чем "огромногсть"?
Основным минусом является глобальная доступность, на мой взгляд. Когда нужно внести очень быстро незначительные изменения в код, возникает большой соблазн не заморачиваться с пересылкой событий и доработкой контроллера, а просто сделать прямое обращение к переменным синглетона. В итоге в сложном проекте эти прямые связи потом вылезают боком.
Понятно, что это целиком в зоне ответственности разработчика, но тем не менее.
А каким образом устроен ваш код, что необходимо наличие одиночки? Что в нем сломается, если одиночку превратить в обычный класс?
Синглетон он на то и синглетон, что содержит ссылку на свой единственный экземпляр. MyClass.instance.
Мне лично больше нравятся целиком статические функции/классы.
mikhailk
возникает большой соблазн не заморачиваться с пересылкой событий
Как ни странно, такого соблазна не возникает - создаются события и все идет своим чередом. К тому же речь идет не обо всех классах подряд, а только о некоторых, которые могут понадобиться в абсолютно любой части программы на любом уровне (как тот же таймер к примеру или класс настроек(именно хранящий эти настройки, а не визуализирующий))
Мне лично больше нравятся целиком статические функции/классы.
Сколько помню, в вопросе между статикой и одиночкой в 99% описывается "победа" за одиночкой (исключение - классы, по функционалу схожие с Math)
GAIKER
А каким образом устроен ваш код, что необходимо наличие одиночки?
Вообще я так понимаю, что народ предлагает следующий подход:
создаем экземпляр класса в к.-л. глобальном контейнере и туда отсылаем события с параметрами, если необходимо достучаться до к.-л. свойства или метода? При этом да, я, как разработчик, наверняка знаю что данный класс будет в единственном экземпляре, но для теоретически командной работы необходим эпизод обучения (к примеру, документация, в общем не суть важно), т.е. формально возможна ошибка, пусть и элементарная. На сколько я правильно понял?
Или может давайте разберем абстрактный пример:
Есть приложение с ветвистой иерархической структурой. В приложении много панелей и поп-апов. В приложении также присутствуют звуки, которые можно настраивать, и при этом изменения записываются в SharedObject. В данном примере ключевыми являются настройка звуков и SharedObject. Если делать так, как я привык, то это были бы 2 одиночки. Если это не правильно, то как правильно?
ЗЫ. тему про MVC читал, но либо не понял, либо мы говорим о разных вещах, в любом случае обсуждение указанного примера, надеюсь, решит проблему.
ЗЗЫ. и спасибо всем, кто пытается научить уму-разуму.
Мне лично больше нравятся целиком статические функции/классы.
Сейчас плююсь и харкаюсь, пытаясь отрефакторить статичный класс, являющийся сервисом, используемым почти всеми приложениями нашей конторы.
Ругаю себя за мысль в том далеком прошлом "а этот класс хорошо бы сделать статическим, чтобы удобно было обращаться". Лучше б, блин, синглтоном сделал.
Сейчас это монтстр, изувеченный if-ами в ходе добавления функционала. Был бы он не статикой - можно хотябы с помощью наследования его расширить было. А сейчас вышел из положения тем что убрал из него всю логику - сделал из него обертку к нормальным человеческим классам (изменить нельзя - придется все приложения перекомпилировать), ну и параметризацию его этими классами.
(Правда, один товарищ благоразумно удержался от лепки if-ов и сделал обёртку для своего приложение над статикой. Но это не сильно щас помогает, потому как функционал нужен многим, а не только его приложению)
Теперь твердо уверен, что статический класс имеет право на жизнь только тогда, когда не имеет состояния (не содержит внутренних/внешних полей) и то не всегда - как его в духе "стратегии" подпихнуть то?
mikhailk
02.01.2011, 22:09
Никто не предлагает лепить все статикой. Но иногда это удобно.
Например, у меня статическим организован SoundProcessor.
Можно было бы его синглтоном сделать, но выигрыша от этого никакого нет.
Однако, сам класс очень небольшой, да и расширять его незачем.
Как ни странно, такого соблазна не возникает - создаются события и все идет своим чередом.
Так а зачем тогда синглтон?
В смысле, чем он отличается от обычного класса?
Я встречал реализацию синглтонов в различных проектах и всегда это затевалось именно в целях глобального доступа к единственному объекту через публичную переменную instance (или что-нибудь типа того). Если не использовать эту особенность синглтона (которая, собственно, и отличает объект синглтона от объекта обычного класса), то зачем вообще использовать синглтон? Для контроля рождаемости? :)
Никто не предлагает лепить все статикой. Но иногда это удобно.
Я тоже так говорил на вопрос "нафига ты этот сервис статикой сделал?" :)
Не, я сам юзаю статику для фабрик контролов, фабрик стилей текстовых полей, для общих, ни от чего не зависящих алгоритмов - пока полёт нормальный (не огреб ещё с ними :) )
Так а зачем тогда синглтон?
В смысле, чем он отличается от обычного класса?
Если есть возможность использовать обычный класс вместо сингтона - нечего и думать - используй обычный - его и тестировать проще и логика яснее и расширять систему удобнее.
Забыл совсем: есть исключение: классы-стратегии можно сделать синглтонами, чтобы не создавать их каждый раз (но это касается только классов без состояния)
А контроль рождаемости - это защита от почесывания правого уха левой пяткой - только лишнее ограничение в коде. Бывало просто: "А теперь нам нужен второй сервис - чисто для ..., т.к. чтобы ... работало надо на другой сервер ходить" - и понеслось:
- перед использованием синглтона лепим флаг "использовать особый сервис"
- лепим внутрь ветку if-а, которая меняет url-ки к которым класс должен обращаться;
- поиспользовали - надо вернуть флаг обратно - чтобы приложение работало
Веселье еще то.
(и при этом всём надеемся, что пока синглтон работает с этими настройками к нему не обратятся другие части приложения, считая, что он настроен по-дефолту)
Для контроля рождаемости?
Собственно да. Фраза кстати порадовала :)
Так вот, мне нужно знать что SharedObject у меня может записываться только в одном экземпляре класса, что никто не перепишет записанное значение. Или тоже самое относительно настроек звука и пр. Т.е. глобальный доступ - да, это удобно, но основное, что мной движет - то, что необходим единственный экземпляр. Почему тогда у меня возникли сомнения? Потому что, к примеру, класс Main (базовый класс приложения) и другие глобальные контейнеры создаются тоже в единственном экземпляре, при этом никому и в голову не приходит реализовывать их через сингл. Вот проведя такую параллель после того как количество одиночек в текущем проекте перевалило за 5, и появились сомнения.
Psycho Tiger
03.01.2011, 13:22
Если на собеседовании претендент утверждает, что знает шаблоны и из всего списка имеющихся приводит только синглтон, то это значит что он их не знает вовсе =)
Наверное, будет интересно пройти у тебя собеседование :D
Почитай тему про MVC. Как только контроллер звука изменил громкость он шлет событие об этом, и те объекты кого это интересует должны это событие услышать.
Это давно у звука есть контроллер? Звук — приблуда вьюхи, максимум читает настройки громкости с модели. Пускать звук кровищи из вены или нет контроллер совсем не касается.
А каким образом устроен ваш код, что необходимо наличие одиночки? Что в нем сломается, если одиночку превратить в обычный класс?
Я использую статик класс SoundMaster для всех-всех звуков. Иногда думаю перейти на синглтон, потому что почти весь мой класс - это композиция с Sound.
Основным минусом является глобальная доступность, на мой взгляд.
Можно не делать глобальную точку доступа. Синглтон - это один экземпляр класса в памяти. Откуда пошла "глобальность" для синглтона - загадка.
Сколько помню, в вопросе между статикой и одиночкой в 99% описывается "победа" за одиночкой
Синглтон нужен если класс наследуется от другого класса или реализует интерфейс. Во всех остальных случаях победа за статикой, коих большинство.
Ругаю себя за мысль в том далеком прошлом "а этот класс хорошо бы сделать статическим, чтобы удобно было обращаться".
Скорее дело не в статике и не в синглтоне. "Махины" вообще в глобальность выносить не надо.
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.