Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.03.2016, 23:33   #1
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
Вопрос Синглтон и паттерн. Что это такое и с чем его едят? (C#))

Собственно и добавить нечего.
Что-то я не совсем вник что это за штуки такие? А точнее вообще не вник.
Реально ли эти вещи объяснить более приближенным к человеческому языку понятиями? Может быть продемонстрировать какие-нибудь примеры.
По быстрому поиску нарвался вот на эту статею на хабре. Исходя из нее у меня мелькнула мысль, что Singleton - это класс, который может иметь только один экземпляр класса. НО! Почитав комментарии к этой же статье, а именно вот этот, у меня начало складываться впечатление, что я где-то что-то не до понял. И если, допустим, первая моя мысль была верна, то как тогда в синглтоне регулируется количество возможных экземпляров?
Заранее спасибо за помощь.
max_prorok вне форума Ответить с цитированием
Старый 16.03.2016, 23:45   #2
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Кажется нашел более менее объяснение, что такое синглтон. Вот этот код наглядно демонстрирует, почему он может иметь один экземпляр.
Код:
public sealed class MySingleton  
{  
    static MySingleton myInstance = null;  
  
    MySingleton()  
    {  
    }  
  
    public static MySingleton MyInstance  
    {  
        get  
        {  
            if (myInstance == null)  
            {  
                myIinstance = new MySingleton();  
            }  
            return myInstance;  
        }  
    private set;  
    }  
}
Теперь осталось разобраться, для чего нужны такие классы. Ну и конечно же понять что такое паттерн.
max_prorok вне форума Ответить с цитированием
Старый 17.03.2016, 00:06   #3
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Что-то я не совсем вник что это за штуки такие? А точнее вообще не вник.
Реально ли эти вещи объяснить более приближенным к человеческому языку понятиями?
Так оно и так на человеческом. Проблема только в том что на английском.
сингелтон, перепечатка с английского SingleTon. Тут видно что слово состоит из двух. До словно переводится как "один тон". Кто с музыкой знаком должен понять.

Цитата:
Исходя из нее у меня мелькнула мысль, что Singleton - это класс, который может иметь только один экземпляр класса
Всё верно.

Цитата:
НО! Почитав комментарии к этой же статье, а именно вот этот, у меня начало складываться впечатление, что я где-то что-то не до понял.
Просто вы вырвали комментарий из окружения вот и поняли неправильно.

Цитата:
то как тогда в синглтоне регулируется количество возможных экземпляров?
Зависит от языка программирования. Можно придумать разные способы. И как правило неправильные.
В C# правильным является объявление статического класса.
А неправильные можете посмотреть как всегда в wiki.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 17.03.2016, 00:34   #4
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

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

То вот к примеру в OpenGL где у вас может быть всего 10 аппаратных точечных источника света, то менеджер который будет виртуализировать(эмитировать работу бесконечного числа) должен быть один. Иначе если вы создадите 2 менеджера. То они будут думать что у каждого 10 и в сумме получиться 20. И при попытке выделить 5 + 6 источников мы получим ошибку. Что-бы её потом долго не искать проще обезопасится заранее запретив создавать повторные классы.

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

Что такое паттерн предлагаю прочитать тут:
https://ru.wikipedia.org/wiki/Шаблон_проектирования
Гамма Э., Хелм Р., Джонсон Р., Влиссидес Дж.-Приемы объектно-ориентированного проектирования (2001)

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

Последний раз редактировалось Pavia; 17.03.2016 в 00:44.
Pavia вне форума Ответить с цитированием
Старый 17.03.2016, 09:53   #5
max_prorok
Форумчанин
 
Регистрация: 06.10.2011
Сообщений: 181
По умолчанию

Спасибо большое за помощь. Вчера ночью где-то вычитал и понравилось сравнение синглтонов с бухгалтерией на предприятии. Если представить программу в виде какого-то предприятия. То у предприятия может быть только один отдел бухгалтерии (о черных бухгалтериях я молчу), и соответственно иметь предприятию две бухгалтерии как минимум не выгодно, а там смотри и мешать друг другу будут. Собственно, как и пример с OpenGL. А то я сейчас начал изучать менеджер слабых событий, а там столько непонятных слов...=)
max_prorok вне форума Ответить с цитированием
Старый 18.03.2016, 10:23   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
В C# правильным является объявление статического класса.
Это ж не тоже самое, в некоторых ситуациях статический класс не подойдет. Например, если нужно реализовать интерфейсы и т.п., или если нужно что-то инициализировать не сразу, а при первом использовании ("lazy"), то синглтон может быть удобнее.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 18.03.2016, 12:20   #7
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Это ж не тоже самое, в некоторых ситуациях статический класс не подойдет. Например, если нужно реализовать интерфейсы и т.п., или если нужно что-то инициализировать не сразу, а при первом использовании ("lazy"), то синглтон может быть удобнее.
Если у вас есть кроме аргументов ещё и реальные примеры. То хотелось бы их увидеть.
А пока вот вам мои аргументы.
Таких задач где одновременно надо то и то не существует. Это два отдельных класса задач. Если вам нужны интерфейсы, то сингелтон вам не нужен.
В противном случае это говорит о том что у вас неправильная архитектура. Вы используете одиночку, там где должен быть обычный класс. Тоже самое и для отложенного создания. Объект один, а значит его можно создать сразу.

Есть маленький такой плюсик. Когда у вас не хватает ресурсов, к примеру памяти, для создания ещё одного класса. Тога имеет смысл по очереди: создал - разрушил, создал - разрушил. Но опять таки это надуманный пример и реально такое не бывает.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 18.03.2016, 12:22   #8
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,708
По умолчанию

Цитата:
Тоже самое и для отложенного создания. Объект один, а значит его можно создать сразу.
Вот и висят такие монстры в памяти, отожрав по 500 МБ и захватив ресурсы, а мы потом смеемся над высказыванием про 640 Кб для всех...
p51x вне форума Ответить с цитированием
Старый 18.03.2016, 13:29   #9
ds.Dante
Старожил
 
Аватар для ds.Dante
 
Регистрация: 06.08.2009
Сообщений: 2,992
По умолчанию

Цитата:
Сообщение от max_prorok Посмотреть сообщение
По быстрому поиску нарвался вот на эту статею на хабре.
Очень хорошая статья, описывает все нужные детали.

Цитата:
Сообщение от max_prorok Посмотреть сообщение
Почитав комментарии к этой же статье, а именно вот этот, у меня начало складываться впечатление, что я где-то что-то не до понял.
Если у вас две бухгалтерии (белая и чёрная), то лучше сделать 2 синглтона в одном классе, чем копипастить 2 статических класса.

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

Если вам не нужны фичи именно синглтона, используйте статический класс, в C# это упрощает код.

Лично я чаще всего пользовался синглтоном в реализации настроек программы. Настройками пользуются несколько частей программы, поэтому точка доступа должна быть глобальной. Но экземпляра должно быть два (defaults и кастомизация), и второй экземпляр нужно сериализовать, поэтому static class не катит.

Последний раз редактировалось ds.Dante; 18.03.2016 в 13:33.
ds.Dante вне форума Ответить с цитированием
Старый 18.03.2016, 13:32   #10
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

Цитата:
Объект один, а значит его можно создать сразу.
Фу, какое гадкое предположение. Минус вам, не обессудьте. Надеюсь, вы сами понимаете абсурдность этих своих слов

Цитата:
создал - разрушил, создал - разрушил
Синглтон на слабой ссылке?

Цитата:
Если вам нужны интерфейсы, то сингелтон вам не нужен
Ситуации бывают разные. Специально насаждать сильную связанность (т.е. обращение без интерфейса) вредно, поскольку гибкость кода страдает.

Цитата:
Если у вас есть кроме аргументов ещё и реальные примеры. То хотелось бы их увидеть.
Реальный проектный код не покажу, но приведу пример, близкий к реальности:

Есть некоторое действие. PerformAction(). Есть интерфейс, который содержит описание этого метода. IActionPerformer. И есть две различные реализации этого метода: которая быстро создается (LightPerformer), но требует больше памяти, и та, которая требует больших ресурсов (процессорное время) на создание (HeavyPerformer), но потребляет мало памяти. В клиентском приложении используется некий IoC контейнер (Unity, Mef, ... - без разницы) для получения IActionPerformer'а.

В зависимости от некоторых условий в контейнере регистрируется либо LightPerformer, либо HeavyPerformer. При этом, LightPerformer регистрируется как "пересоздаваемый класс", а HeavyPerformer как Instance класса, и не пересоздается (ибо его пересоздание - дорогая операция).
В данном случае, HeavyPerformer обладает всеми признаками синглтона (единственный экземпляр, глобальная точка доступа через контейнер), но при этом реализует интерфейс, и архитектура приложения ничуть не пострадала.

Код:
 
    public interface IActionPerformer
    {
        void PerformAction();
    }

    internal class LightPerformer : IActionPerformer
    {
        private byte[] longData;

        public LightPerformer()
        {
            longData = new byte[1024 * 1024 * 512];
        }

        public void PerformAction()
        {
            // do someting
        }
    }

    internal class HeavyPerformer : IActionPerformer
    {
        public HeavyPerformer()
        {
            Thread.Sleep(3000);
        }

        public void PerformAction()
        {
            // do someting
        }
    }

    public class SomeClass
    {
        public SomeClass()
        {
            // initialization
            if (someCondition)
                Container.RegisterType(typeof(IActionPerformer), typeof(LightPerformer));
            else
                Container.RegisterInstance(typeof(IActionPerformer), new HeavyPerformer());
        }

        public void DoAction()
        {
            IActionPerformer performer = Container.Resolve<IActionPerformer>();
            performer.PerformAction();
        }
    }
Если нужен пример "чистого синглтона" в классическом его понимании в C# (т.е без IoC и прочих фокусов), в котором реализован интерфейс, и это не адов костыль, то могу и его расписать

А синглтон сам по себе в чистом виде - довольно спорная конструкция. Нафиг не нужная в большинстве случаев. Хотя однозначно к антипаттернам я относить бы его не стал
Благодарить в репутацию. Проклинать — туда же

Последний раз редактировалось Luuzuk; 18.03.2016 в 14:08. Причина: добавил "код"
Luuzuk вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Что такое отладчик с чем его едят и как его использовать Dimka-novitsek Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 1 20.03.2014 17:59
Класс-контейнер? Что это такое и с чем его «едят»? 4atty Общие вопросы C/C++ 1 12.03.2013 00:43
Что такое Flash и с чем его едят... coolartemka JavaScript, Ajax 1 18.05.2011 02:40
<< >> & ^ | с чем это едят и что это такое? pufystyj Общие вопросы C/C++ 4 30.03.2011 13:59