Паттерн Singleton

А давайте расскажу интересное — про паттерн проектирования Синглтон. Кто-то знает и пользуется, а кому-то вдруг и пригодится.

forever singleton

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

Синглтон («Singleton» — одиночка) используется в случае, если на все приложение необходим только один экземпляр определенного класса, доступ к которому можно будет иметь из любого места.

Предположим, что мы имеем некий класс SoundManager, который отвечает за воспроизведение всех звуков в игре. Скажем, есть у него публичный метод playExplosionSound(). До того, как мне стало известно о синглтоне, для того, чтобы вызвать этот метод из какого-нибудь глубоко упрятанного класса, приходилось делать что-то вроде myParent.myParent.soundManager.playExplosionSound(), а то и ещё померзостней.

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

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

package  
{
        public class SoundManager
        {
                public static var instance: SoundManager;

                public function SoundManager() 
                {
                        if (instance) throw new Error ("Class is singleton!")
                        else instance = this;
                }

                public function playExplosionSound():void
                {
                        trace("Ба-бах!");
                }
        }
}


Уже неплохо. Теперь единожды где-нибудь после старта приложения создаём экземпляр этого класса при помощи New SoundManager, и обращаемся к нему из любого места так: SoundManager.instance.playExplosionSound();

А что будет если попробовать сделать ещё раз New SoundManager? Получим сразу же эррор: «Class is singleton!».

Но есть и недостаток: во-первых, ничто не помешает нам сделать SoundManager.instance = null (мало ли что вздумается вашей тёмной злой стороне), и, во-вторых, класс надо не забыть инициализировать перед первым его использованием. На такой случай можно использовать другую реализацию синглтона:

package  
{
        public class SoundManager 
        {
                private static var _instance: SoundManager;

                public function SoundManager() 
                {
                        if (_instance) throw new Error ("Class is singleton!");
                }

                public function playExplosionSound():void
                {
                        trace("Ну бабах же!");
                }

                static public function get instance():SoundManager 
                {
                        if (!_instance) _instance = new SoundManager();
                        return _instance;
                }
        }
}

Теперь ничего нигде не нужно инициализировать и создавать, знай используй себе SoundManager.instance где угодно в коде.

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

Спасибо за внимание!
  • +9

Комментарии (100)

+1
А не проще исспользовать всего 1 статический класс и обращатся на 1 точку быстрее.

[code]
SoundManager.PlayTestSound();
[/code]

например?
  • Vel
  • Vel
+1
Проще. Сам всегда так делаю. Но не всегда лучше.

Допустим для звукоменеджера — это вряд ли, но могут быть объекты которые сегодня синглетон, а завтра уже нет. У меня так было, когда я сделал игру синглетоном, а потом захотел иметь две игры одновременно.

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

А чтобы не геморроится с зависимостями и кто кого когда создает, желательно освоить концепции лежащие в основе RobotLegs например. Но я пока на практике это все не применял :-) Зато в теории очень красиво и просто.
0
www.slideshare.net/RaimundasBaneviius/mvc-express-presentation-11974348
+1
Боюсь, твой метод годится для «утилитных» классов, но неприемлем для классов «серьёзных», имеющих собственные переменные и порожденные объекты.

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

Т.е. такое, например, не пройдёт
<...>
private var _explosionSound: Sound = new ExplosionSound();
private var _soundChannel: SoundChannel;
<...>
// а дальше - статический метод не катит
public static method playExplosionSound():void
{
  _soundChannel = _explosionSound.play(); // это, естественно, выдаст ошибку
}
0
Что мешает переменные тоже сделать статическими, раз уж это синглтон?
+1
Повесишь на статический класс слушатель — отказываюсь от синглтона!
0
Ну если уж нужны слушатели, то тогда наверное никак…
+2
Легко


public static var dispatcher:EventDispatcher = new EventDispatcher();
...

StaticClass.dispatcher.addEventListener(...);
0
Твой пример — синглтон, только беззащитный :) его поломать легко
0
Добавить геттер/сеттер? )
Вопрос же был повесить слушатель, а это уже отмазки пошли )
0
:P
0
похоже еще один человек освобожден от рабства синглтона :)
0
P.S. Не пользуюсь синглтоном, как костылем для шаринга. Просто участвую в дискуссии )
0
А чем пользуешься?
0
MVC
0
Какой-то фреймворк или всё сам?
Не опишешь чуть подробнее в контексте игр?
+6
Никаких фреймворков, пара базовых классов и строгое соблюдение архитектуры. Поначалу кажется, что занимаешься херней и неоправданным раздуванием кода. Спустя какое-то время все доходит до автоматизма и уже совсем не парит и даже через год можно вносить в проект сколь угодно существенные изменения практически с налету. Взамен я получаю архитектуру игры, при которой каждый класс решает свою маленькую задачу без оглядки на остальных и все необходимое получает в конструкторе — вот почему у меня в коде никогда не стоит задача «глобального доступа».

И да, абстракцию — фтопку. У меня только утилиты и базовые классы кочуют из приложения в приложение. А так чтобы куски кода — не припомню. Да и смысла в этом нет, потому что при соблюдении установленных правил новые окна игры, гуй и прочие элементы создаются с нуля как по маслу.
+1
эх, еще бы примерчик :-)
+2
С этим в рамках комментариев сложнее:

1. маленьких хороших примеров MVC не бывает
2. пример любого MVC вызовет массу новых вопросов, обсуждений и холиваров, типа «кто заведует логикой: модель или контрололер?!» или «если контроллер такой тонкий, зачем он вообще нужен» и далее в таком духе

Если есть желание окунуться в эту тему, рекомендую топик на Flasher.ru, который предоставляет читателю много страниц вопросов, споров, ответов, советов, практических примеров и прочих в конечном счете познавательных и полезных суждений. Именно после этой темы я начал активно использовать MVC в качестве основы моих приложений.

P.S.
И я походу еще кромешный нуб в этом плане. Просто нравится. Просто использую. Просто рекомендую :)
0
mvc хорош там где есть четкое разделение данных-представлений-действий. А игры — это сплошные действия и представления, а данные болтаются между ними в каких угодно соотношениях, поэтому там с этим подходом тяжеловато (мне).
0
mvc хорош там где есть четкое разделение...
А где его нет :)
0
«строгое соблюдение архитектуры» — это самое ключевое считаю :) а там уж без разницы какой подход использовать. Заметил, все проблемы наступают когда разок другой плюнешь на правила и сделаешь через жопу лишь бы побыстрее.
+1
Ну так сделать переменные статичными и все
0
+1. Как будто кто-то кроме нас будет использовать этот код, а уж сам-то никогда не забудешь про то, что можно, а что нельзя. Вобще статика она на то и статика, чтобы инициализироваться только один раз за все время жизни приложения, и если больше то это уже кривая архитектура (всякие глобальные счетчики не в счет).
+2
Идея описывать паттерны это плюс. Но не синглтон же @_@
Во-первых, упоминание о синглтоне всегда порождает эпик срач.
Во-вторых, его уже где только не описывали все кому не лень.

P.S.
Картинка доставляет ;D
0
Замечено, что безобидный вопрос на форумах «подскажите, как сделать синглтон» всегда порождает обсуждение на пару десятков страниц. Было интересно
0
Замечено, что безобидный вопрос на форумах «подскажите, как сделать синглтон» всегда порождает обсуждение на пару десятков страниц. Мне интересно мнение нашего сообщества, как отреагируют здесь — да и, уверен, интересный мыслей тоже будет озвучено много :)
+1
Есть ещё вариант — инициализация при объявлении:

package  
{
        public class SoundManager
        {

                public static var instance: SoundManager = new SoundManager();

...
        }
}


Можно ещё просто сделать глобальную (ох, сейчас полетят камни) переменную soundManager.as:

public var soundManager:SoundManager = new SoundManager();

или
public var soundManager:SoundManager = SoundManager.instance;
  • Regul
  • Regul
+2
Давайте же устроим срач!) Что хорошего в синглтоне я понимаю. А что плохого? Кроме трудностей с юнит-тестами?
+2
Йееееее! Срааааач!
Я вижу плохое в скрытых зависимостях. Так бы взял класс да перенёс бы целиком в другой проект — а тут вдруг бац! и выясняется, что он завязан каким-то странным образом с ещё другими классами, которые хз как связаны, в свою очередь, между собой.
+1
Ок. А как избежать связности не используя синглтон? Допустим, как в примере, это будет саунд менеждер.
Где то в коде моего класса:

SoundManager.instance.play(SOUND_BOOM);


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

private var _soundManager:ISoundManager;

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

Это «противоположность» синглтону, или есть еще способы?
0
Вспомнил еще про события. А есть ли еще варианты?
0
Действительно, зачем придумывать, если все уже придумали.

Статика очень вредна при росте проекта, при рефакторинге чаще всего от нее отказываешься или создаешь еще большие уровни абстракции типа StaticManager, StaticManagerImpl, StaticManagerImpl2 и т.д.
  • deep
  • deep
+2
Синглетон — такое же зло, как goto. То есть теоретически могут быть ситуации, когда с ним будет лучше/проще, чем без него, но на практике часто себя потом матюкаешь матюками за то, что поддался.
+5
Синглтон — это инструмент.
А если человек наносит себе увечья отверткой или молотком, то это проблемы его, а не инструмента.
+1
Инструменты бывают хорошие и бывают плохие. Синглетон — плохой инструмент. Потому что с одной стороны он нафик не нужен, а с другой — опасен.

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

А вот обратная ситуация, когда начитавшись шаблонов их вставляют везде для того, чтобы быть крутым («Я использую шаблоны») — это зло.
0
Расскажи-ка мне, какие у синглетона плюсы? Позволяет передать в функцию на один параметр меньше?
0
Слушай-ка:
Синглтон («Singleton» — одиночка) используется в случае, если на все приложение необходим только один экземпляр определенного класса, доступ к которому можно будет иметь из любого места.
+1
Что-ты хотел сказать копипастой из википедии?

Тут два варианта. Ну, самых очевидных. Возможно, их больше. Первый — это антипаттерн God Object (а потому нужно не лепить сюда синглетоны, а подумать над архитектурой приложения). Второй — на самом деле можно этот объект передать в методы просто дополнительным параметром (как в случае, с саунд менеджером).
0
Я не программист. До синглтонов догадался сам — только потом узнал как это называется:) Но использую и их и передачу инстанса в методы. Иногда вторым способом получается сложнее. Например если проект уже достаточно велик по объёму, и чтобы ссылочку на класс звука передать по всей архитектуре классов — уйдёт уйма времени.
0
синглтон отличается от примитивной статики по факту только одним — защитой от дурака. Если ты в себе уверен, и уверен, что тебе нужно что-то глобальное, используй статику: всего одна строка, и код вызова писать меньше.
0
Ну крутые перцы вообще на C пишут и в гробу видали все эти ваши паттерны. Но мы же не они, правда? :)
0
Пример из книжки Real World Flash Game Development.
Хорошая, кстати, книжка.
А я использую синглтон и считаю его вполне удобным.
+3
В программах, написанных одним человеком, которые никто и никогда не будет дорабатывать, например, во флеш-играх, можно использовать всё, что душе угодно. Другое дело, когда, не дай бог, такие вот любители синглетонов, начинают работать в коллективе программистов…

Есть, допустим, у тебя игра. В ней стопятьсот классов, всякие там методы в них есть, местами используется этот ваш синглетон для сайнд менеджера. И всё здорово, вроде бы:
public function mySomeMethodNumber100500(): void
{
    SoundManager.instanse.play(SOUND_COOL);
}

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

Твои действия?
+1
А нет универсального инструмента, есть подходящий для конкретного случая.
Многие здесь работают в коллективе программистов?

А вдруг завтра надо будет переписать на другом языке все?
Нужно решать проблемы по мере поступления, а не пытаться предусмотреть все.
+1
В том суть паттернов заключается, чтобы некоторые типичные проблемы предусмотреть и обойти заранее. Потому что на этих проблемах не одну тысячу раз набивали шишки другие люди. Одна из таких проблем — связность системы, которая при помощи синглетона не решается, а наоборот усугубляется и часто многократно. Потому умные дядьки давно пришли к выводу, что синглетоны есть зло. Некоторые же программеры вместо того, чтобы послушать умных людей, почему-то продолжают бодать ворота. Ну, как говорится, флаг в руки.
0
Используй синглтон внутри своего модуля (компонента), как это усугубит связность всей системы?
+2
Это усугубит связность модуля :)
0
соглашусь, но как раз именно поэтому синглтон использовать не нужно.
0
прежде чем написать что-то большое, необходимо сначала это что-то большое спроектировать.
как правило реального коддинга в приложении лишь 30%, остальные 70% — проектирование.
если вы изначально спроектировали приложение так, что чтоб его оттестировать приходится страдать вот такой канителью, как вы описали, то смысл такого проектирования?
0
Ты что-то вот сейчас намешал всё в кучу.

Страдать канителью приходится при плохом проектировании, да. Синглетон — признак плохого проектирования, да. Если бодяжить в код синглетоны, то потом сложно будет его тестировать, да.
0
Окей, тогда перейдем в другую позицию.
Тебе нужно загрузить конфиг.хмл и получать к нему доступ в любое время из любой точки программы, цапая оттуда нужные тебе данные. Как поступим?
0
Ну, очевидно, что синглетон — тут неправильное решение. Хотя бы потому что (например, в тех же тестах) тебе запросто может понадобиться подсунуть фейковые данные вместо того xml. Загружаем xml, парсим/десериализуем, готовый объект передаём тем, кто в этом нуждается… желательно по интерфейсной ссылке.
0
то есть заставляем все наши классы наследовать интерфейс, лишь для доступа к хмл?
и в каждый класс передаем ссылки на хмл?
хороший подход.
0
Какие все классы? Нет, конечно. В те методы, которые нуждаются в данных из этого xml просто добвляем параметр:
// было:
function mySomeFunc(): void {
    // ...
}

// стало:
function mySomeFunc(config: IConfig): void {
    // ...
}
+1
и каждый метод перегружаем лишним параметром, лишь потому что синглтон это очень плохо?
не пойму в чем преимущество такого подхода.
0
Не каждый, а только те, которым нужен конфиг. Потом вместо IConfig ты сможешь передавать объект любого типа, который реализует этот самый IConfig.
0
Ладно, я понял. пока серьезно не обожгусь на синглтонах не пойму все сути.
Ты меня не убедил, что синглтоны зло.
Viva la Flash
0
загрузить в static переменную
0
в статик переменную куда? в каждый класс?
мы про синглтон и говорим, что там внутри статик переменная.
0
у меня например есть класс Stats куда я пихаю все статики для игры, доступны они соответственно из любого класса.
0
+1, Понимаю что подход не шибко хорош, но сам так делаю.
0
Пфф. Ещё лучше :))
0
конечно лучше)
0
Тем, что тебе ещё (в добавок к синглетону) нужно не забыть проинициализировать его? :) Причём проинициализировать сторонним кодом…
0
… ну или статическим конструктором. Уж не знаю, что хуже :)
0
Stats.myxml = new XML(e.target.data); не вижу сложностей
+2
Ты же понимаешь, что этот фрагмент кода будет находиться у тебя в таком месте, которое вообще никаким боком по-хорошему не должно относиться к этим вашим xml. Это тупо нарушение инкапсуляции. Это даже хуже, чем синглетон.
0
оно будет находиться там где он загружается)
0
В конструкторе он должен находиться, а не где-то там…
0
так это, я ж не претендую на правильность, просто написал как я делаю) когда особо времени нет то над такими вещами как то не задумываешься.
0
так это, я ж не претендую на правильность, просто написал как я делаю) когда особо времени нет то над такими вещами как то не задумываешься. И про какой конструктор кстати ты говоришь?
0
Про инициализировать сингелтон? Вы серьезно?

сторонним кодом
Вы серьезно?


package com.fg.core
{
    public class Resource
    {
        
        //-----------------------------------------------------------
        //
        // Constructor
        //
        //-----------------------------------------------------------
        
        public function Resource(pvt:PrivateClass)
        {
            
        }

        //-----------------------------------------------------------
        //
        // Properties
        //
        //-----------------------------------------------------------
        
        //-------------------
        // instance
        //-------------------
        
        private static var _instance:Resource;

        public static function get instance():Resource
        {
            if (!_instance)
                _instance = new Resource(new PrivateClass());
            
            return _instance;
        }
}

class PrivateClass{}


Где здесь нужно инициализировать этот класс отдельно если при первом к нему обращении он создает свой экземпляр?
0
В конструкторе. Вон же у тебя пустой конструктор. Дерзай.
0
Вообще, блин, народ, вы хотя бы читайте то, что комментируете. Речь шла про статическую переменную.
Ты же отвечаешь на этот пост и приводишь в пример синглетон, мол, как его инициализировать отдельно. Да никак. Это ж бубль гум синглетон.
+1
А теперь еще раз :) Синглтон, в моем примере, инициализирует себя сам при первом к нему обращении. То, что у меня пустой конструктор, лишь говорит о том, что при инициализации в первый и единственный раз мне ничего не нужно выполнить по-умолчанию.
И еще на заметку просто вызвать конструктор, т.е. создать его instance способом
var resouse:Resource = new Resource();
у вас не получится так как в него передается вспомогательный класс видимый только из самого класса Resource.
+1
А теперь ещё раз :)))) В этой ветке обсуждения речь идёт не о синглетонах, а о статической переменной :)
А ты тут с синглетоном…
0
По видимому упустил суть ветки :) Столько холивара :)
0
опыт говорит, что проектирования по времени — 10% не больше.
0
Везет же вам, у меня проектирование это не меньше 70% а то и больше.
0
А я вот, хоть это и неправильно, наверное, не проектирую вообще. Ну то есть у меня нет такой фазы разработки, когда я бы сидел и проектировал. Оно либо получается как неотъемлимая часть кодинга, либо когда я вообще в далеке от компа и раздумываю над системой.
0
Не помню где это было, но даже из 8 часого дня реально программист пишет код в среднем не более 3 часов или около того. Конечно 70% это немного завышенная цифра :), но то что на проектирование тратится намного больше чем кажется это факт
0
Вот статистика habrahabr.ru/post/35085/
Т.е. всякие есть, но нормальных все-таки больше.
0
Ну опять таки это статистика субъективна. Именно по ощущениям, а не реальная статистика.

Вот тут с пятого абзаца habrahabr.ru/post/102620/

Вот тут Именно та диаграмма про два часа blogerator.ru/page/skolko-v-den-zanimaetsja-kodirovaniem-zapadnyj-programmist. Конечный пруф лень искать да и не могу пока
0
Даже не с пятого а с первого :)
0
Ну не 10-12 строк кода в день — это уже перегиб, ты сам то веришь в это? С такими темпами игры пришлось бы делать годами. Я специально для интереса сейчас подсчитал кол-во строк, написанное за прошлую игру — получается 100 строк в ЧАС (правда с небольшим кол-во коментов). Если бы я писал по 10 строк в день, то писал бы её больше года.
0
Да пишите сколько угодно в час, с чего это мы перешли с почасового расчета на расчет строк в час. Реч о часах потраченых на написание кода. Может еще скорость набора вспомним и слепой метов набора. Я по себе знаю что очень много занимаюсь проектированием, часто часами думаю как сделать, а потом за пол часа все набираю.
0
Как с чего — в приведенной ссылке было про 10-12 строк кода. Я к тому что у меня есть все основания не верить той ерунде, которая там написана.
0
Ну так надо было по линку пойти и почитать и понять, что за 10 строк кода. Дальше не вижу смысла беседы.
0
там написано что это те 10 строк которые остаются в продакшене. Я назвал свою цифру которая реально осталась в последнем релизе игры. Что не так?
0
давненько не использовал, прямо ностальгия)
0
К слову о полезности и бесполезности синглтонов, как паттерна, я например успешно использую этот паттерн в качестве локализатора и это на мой взгляд очень удобно ;)
+2
Еще важные отличия Синглтона от Статики:

— На сколько читал, вся Cтатика инициализируется при запуске программы,
отнимая ресурсы и занимая оперативную память, даже если вы еще продолжительное время не будите ею пользоваться.Синглтон же занимает ресурсы компьютера, именно в момент первого обращения к нему.

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

Минусы:

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

Статику и Синглтон можно заменить другими паттернами проектирования.
К примеру, если требуется «сундук с данными» (обычно это статик переменные: номер уровня, очки и пр.), которые используют много различных классов в программе/игре, то можно применить паттерн Наблюдатель (Observer), для централизации, своевременной целостности и общедоступности данных.

А вообще, чтобы максимально снизить зависимость между классами, получать удовольствие от архитектуры, которая всегда готова к новым изменениям, то надо минимизировать в программе синглтоны, статику, наследование (в зависимости от ситуации) и в противовес применять композицию и паттерны проектирования снижающие зависимости (Стратегия, Наблюдатель, Адаптер, Состояние, Декоратор, Компоновщик и пр., а также связку некоторых из них — модель MVC).

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

К слову, паттерны проектирования очень помогают мне.
Таская код движка от игры к игре, новая адаптация и его расширение
— занимают минимум времени и доставляют большое эстетическое удовольствие,
т.к уже работаешь не рамках кучи мало связанного кода,
а в рамках системы с правилами и гибкой адаптацией.
  • Renat
  • Renat
0
Я не совсем согласен с «важными отличиями».

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

Второе отличие — некорректно, ибо существуют статические конструкторы. Не знаю, правда, как в этом во флеше. Если же их в языке нет, можно писать в каждом методе что-то типа
if (!initialized) {
    init();
    initialized = true;
}
0
То есть моя позиция такова (из предыдущего поста может показаться, что я за статику): и синглетон и статика — суть зло. Синглетон иногда лучше статики, но не на много.
0
К слову, если более точно на счет одного из отличий Синглтона от Статики, я имел ввиду Отложенную (ленивую) инициализацию.
  • Renat
  • Renat
0
А что мешает в конструкторе статика ничего не писать, а сделать метод Init?
0
Есть вероятность, что ф-я Init() будет пропущена пользователем, и вызвана другая статик функция первой, в результате будет ошибка. Как уже писал выше, здесь я не имею ввиду классы-утилиты, обычно там каждая статик функция сама по себе.
В данном случае, можно выдать сообщение об ошибке «Предварительно вызовите ф-ю Init», но Синглтон решает эту задачу лучше.
0
Меня в таких случаях часто жаба давит. Если синглетон юзается очень уж часто, то очень много раз вызывается внутри него if, который проверяет, есть ли уже инстанс или ещё нету. И в 99.99999% оказывается, что инстанс уже есть :) Т.е. холостая работа. Хотя, не знаю, насколько это критично.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.