Singleton — паттерн или антипаттерн?

     

    Only registered users can participate in poll. Log in, please.

    Singleton — паттерн или антипаттерн?

    • 10.6%Singleton — это по сути те же глобальные переменные, то есть ужасное зло46
    • 8.9%Singleton — это по сути те же глобальные переменные, то есть великое добро39
    • 7.8%Singleton — это совсем не глобальные переменные, но всё равно ужасное зло34
    • 45.2%Singleton — это совсем не глобальные переменные, и к тому же великое добро197
    • 27.5%Что такое Singleton?120

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 35

      +11
      Синглтон — зло, когда применён не к месту. Разве нет?
        +9
        [Полный перебор значений] — зло, когда применено не к месту. Разве нет?
          +1
          Да, мой комментарий был «капитанством». Но разве при этом комментарий не справедлив? В вариантах ответов — одни крайности: «великое добро», «ужасное зло». Просто надо усиленно думать при применении любого кусочка кода. К синглтону это тоже относится, даже сильнее. Лично я синглтоны употребляю только при острой необходимости.
          +1
          Проблема в том, что простота этого паттерна стала причиной ПОСТОЯННОГО применения Синглтона не к месту.
          Хотя, вот лично я, не могу представить, когда он может быть нужен на практике.
            +8
            Ну и да, Синглтон имеет кучу недостатков:

            1. Синглтон нарушает SRP (Single Responsibility Principle) — класс синглтона, помимо того чтобы выполнять свои непосредственные обязанности, занимается еще и контролированием количества своих экземпляров.
            2. Зависимость обычного класса от синглтона не видна в публичном контракте класса. Так как обычно экземпляр синглтона не передается в параметрах метода, а получается напрямую, через getInstance(), то для выявления зависимости класса от синглтона надо залезть в тело каждого метода — просто просмотреть публичный контракт объекта недостаточно. Как следствие: сложность рефакторинга при последующей замене синглтона на объект, содержащий несколько экземпляров.
            3. Глобальное состояние. Про вред глобальных переменных вроде бы уже все знают, но тут та же самая проблема. Когда мы получаем доступ к экземпляру класса, мы не знаем текущее состояние этого класса, и кто и когда его менял, и это состояние может быть вовсе не таким, как ожидается. Иными словами, корректность работы с синглтоном зависит от порядка обращений к нему, что вызывает неявную зависимость подсистем друг от друга и, как следствие, серьезно усложняет разработку.
            4. Наличие синглтона понижает тестируемость приложения в целом и классов, которые используют синглтон, в частности. Во-первых, вместо синглтона нельзя подпихнуть Mock-объект, а во-вторых, если синглтон имеет интерфейс для изменения своего состояния, то тесты начинают зависеть друг от друга.
              0
              2. В случае ServiceProvider'ов зависимость тоже не видна.
              3. Уместно применённый синглтон, только stateless.
          +7
          Мой вариант: Singleton — это совсем не глобальные переменные, и… иногда можно
            0
            > и… иногда можно

            Иногда даже бывает просто необходимо, ибо без них пришлось бы городить костыли и подпорки.
            0
            Вообще-то это далеко не только переменная, это все-таки класс, который можно наследовать и изменять его поведение
              –2
              добро же.
              например паттерн реестр через синглтон самое то организовывать, да и еще кучу вещей.
                +3
                Сингелтон убивает композицию.
                  +4
                  Конечно, Single Tone — это монофонический синтезатор, звучание же грубое и ужасное, любую компощицию похоронит.
                  +3
                  Кстати статья для интересующихся: Implementing the Singleton Pattern in C# Скита (Многие ее уже видели и используется там специфика C#, но всеж).
                    +1
                    Спасибо за ссылку!
                    Я например еще не эту видел статью. Про Lazy не знал. Интересная штука.
                    +2
                    ИМХО, как и goto в C++ — хоршая штука если точно знаешь где и как его применять. Даже не так — ТОЧНО знаешь :). Во всех остальных случаях, увы, порождает спагетти-код :(.
                      +1
                      отлично, а причем здесь синглтон?
                        +6
                        Даже не знаю как ответить, вы меня прямо в тупик поставли :). Потому что гладиолус?
                        +1
                        Приведите пример этого спагетти, чтоль. Только такой, чтобы синглтон был «настоящим» и было понятно, что спагетти из-за него, а не от откровенно кривых рук.
                          +3
                          Да легко.
                          — Использование синглтона для хранения кэша спрайтов. «Ну он же общий для всех!».
                          — Использование синглтона для доступа к настройкам приложения. Смешно? А вот когда их обновлять в рантайме приходится, становится не смешно :).
                          — Использование синглтона для доступа к базе данных. Да-да, то самое, эталонное. Как потом красив и прекрасен код, когда баз данных становится больше одной…
                            0
                            В Cocoa у Apple кстати настройки приложений сделаны через синглтон — крайне удобно.
                              +1
                              Я помню. И именно поэтому большая часть программ в App Store осень мучительно переживают смену этих самых настроек в программе и требуют выхода и входа для их применения ^_^.
                                0
                                Вы про Cocoa Touch? Я если честно не в курсе в чем там отличии, но предполагаю что просто кривой какой-то кривой.

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

                                  BTW, напоминаю, что у меня пример того, как синглтон может быть использован неправильно. Он там может быть использован и правильно. Есть много случаев, когда доступ к настройкам через синглтон — самое то. Моя позиция тут в том, что нужна достатоно высокая квалификация, чтобы определить где синглтон стоит применять, а где не стоит. И это не есть хорошо, на мой взгляд.
                                    0
                                    Эм, а как же иначе вы планируете уведомлять определенные части приложения что что-то где-то изменилось? Мне приходилось видеть действительно адовый код — код который отвечает за настойки начинает уведомлять разные части приложения (он вообше не должен про них кстати знать), что что-то он тут поменял. Потом программа разрастается, появляются еще места которые могут менять теже самые настройки и они начинают дублировать код опять связываясь с разными частями приложения про которые они знать и не должны.

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

                                    А перезаходить в приложения (я уж почитал что там к чему в iOS) — это действительно кривой код новичков. Им нужно почитать что-то вроде «Cocoa Design Patterns».
                              0
                              Простите, спрайты не кэшировал, но с более близким мне примером доступа к настройкам в чем проблема с синглтоном? и как это делается правильно без него?
                                +1
                                См. мой ответ выше. Боюсь, «правильно» не существут — архитектура программ, увы, слишком сильно зависит от типа этих программ :(. Моя позиция не в том, что синглтон плох — а в том, что требуется достатоно высокая квалификация, чтобы определить где синглтон стоит применять, а где не стоит. И это не есть хорошо, на мой взгляд.
                          +7
                          Паттерн сам по себе вполне не плох. А вот реализации иногда заставляют плакать.
                            0
                            Считаю злом.
                            Исчерпывающее обсуждение в java-контексте:
                            stackoverflow.com/questions/28241/java-singleton-vs-static-is-there-a-real-performance-benefit
                              0
                              На мой взгляд, ответ не однозначен. Я разрабатываю на perl, он вполне позволяет обозвать синглтоновский метод для получения экземпляра объекта как угодно. Если я называю этот метод так же, как типовой конструктор — new — то в будущем при необходимости могу спокойно отказаться от паттерна, или поменять логику его работы, и снаружи объекта об этом никто не узнает. Есть метод, который возвращает экземпляр, а уж откуда он берется — это его личное дло. Это — добро, т.к. оно дает гибкость, не забирая ничего взамен. Если ЯП не позволяет проделать такой трюк (кажется, в той дискуссии фигурировал С#, но уже не уверен), и я вынужден по-книжному называть метод именем instance, то уже по названию метода видно откуда он взялся и что делает, и это не совсем добро. Но все-таки лучше глобальных переменных, т.к. вы все еще можете изменить реализацию этого метода, хотя если метод с названием instance внезапно начнет возвращать разные объекты, вас проклянут потомки…
                                0
                                Паттерн — зло, он сходу нарушает два базовых принципа ООП — наследование и полиморфизм, так как вызывая класс напрямую по имени его уже не заменишь ни на наследника, ни на аналог, при этом добавляя связанным с ним классам такую характеристику как неподвижность, так как объект который считывает связи с другими объектами из, например, реестра объектов (реализованного через синглтон) — без самого реестра объектов работать уже не будет, это тоже так сказать базис — объект должен получать заведомо необходимые ему для работы данные через конструктор, опциональные — через аксессоры. Но это теория.
                                На практике конечно не всегда все так однозначно, есть классы сугубо специфичные для приложения, не предназначенные ни для наследования, ни для отдельного использования, например классы команд фронтального контроллера, в них синглтон может быть альтернативой протаскиванию необходимых объектов через всю иерархию классов.
                                  +1
                                  А если у меня есть универсальная фабрика, которая может произвести любой объект с любыми параметрами и ее синглтон — это тоже неправильно?
                                  0
                                  Когда альтернатива глобальные переменные — я выберу синглтон, получаемый через фабрику (использование в 100500 местах программы $obj = ClassName::getIntstance() мне почему-то нравится куда меньше, чем $className='ClassName'; $obj = Fabric::get($className);
                                    0
                                    Не пишите так больше пожалуйста.
                                      0
                                      Вам не нравится $объ = Материя:: получить($классИмя)? :)
                                    +1
                                    Главное применять в нужном месте, а не везде где хочется.

                                    Only users with full accounts can post comments. Log in, please.