1. Акция на весь декабрь! Получай оплату х2 за уникальные статьи, объемом от 200 слов, если в заголовке темы и теле статьи присутствует слово Python
    Скрыть объявление

Обобщение Singleton паттерна

Тема в разделе ".NET", создана пользователем NikSoft, 19 ноя 2006.

  1. NikSoft

    NikSoft Гость

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

    Код (Text):
    using System;

    namespace SerialPorts
    {
    ////////////////////////////////////////////////////////////   
    class Program
    {
    static void Main(string[] args)
    {
    SerialPort serialPort1, serialPort2, serialPort3;

    try
    {
    serialPort1 = new SerialPort(1);
    serialPort2 = new SerialPort(2);
    serialPort3 = new SerialPort(3);
    }
    catch (SerialPortException spe)
    {
    Console.WriteLine(spe.Message);
    }

    Console.ReadLine();
    }
    }

    ////////////////////////////////////////////////////////////
    class SerialPort
    {
    static int _instanceNumber;
    int      _portNumber;

    public SerialPort(int portNumber)
    {
    if (_instanceNumber > 1)
    {
    throw new SerialPortException("No more than 2 serial ports allowed");
    }
    else
    {
    _instanceNumber++;
    _portNumber = portNumber;
    Console.WriteLine(String.Format("Starting to work with serial port {0}", _portNumber));
    }
    }
    }


    ////////////////////////////////////////////////////////////
    class SerialPortException: Exception
    {
    public SerialPortException(string s): base(s){}
    }

    }
    Как видно из кода, при попытке создать третий обьект типа SerialPort выдается сообщение
    “Разрешено рабатать на более чем с двумя последовательными портами”.
    Данный код легко модифицируется для конкретных нужд разработчика.
     
  2. eisernWolf

    eisernWolf Гость

    Singleton уже давно себя исчерпал. Его использование не рекомендуется, хоть обобщай, хоть не обобщай. Сейчас применяется красивая модель сервисов (Dependency Injection). Иногда статических классов (ну любят их в Microsoft)... Да и откровенно говоря, я и Singleton-a тут не вижу. Если и нужно ограничить количество экземпляров класса, то делается это совсем по другому (конкретная реализация зависит от целей).
     
  3. Dr.Gigabit

    Dr.Gigabit Гость

    Что то не могу уловить связи между IoC (он же DI) и Singletonами?
     
  4. eisernWolf

    eisernWolf Гость

    Смысл в том, что если дизайн построен на сервисах, то синглтонов можно избежать (например, передавать сервис в контексте, т.е. наследнике IServiceProvider). Сейчас эту модель Microsoft активно раскручивает в WCF: ...GetService<...>();
     
  5. karlito

    karlito Гость

    Для: NikSoft
    Оценка коду 2.
    Без комментариев. Уж больно много писать.

    Для: eisernWolf
    Ты, брат, тут не прав.
    Не нужна мне красивая модель. Мне нужна рабочая, проверенная модель. Я не думаю, что появился паттерн, который решает те же проблемы что и Singleton. Смысл во придумывании 2-ого колеса?

    Не нужно буровой машины, если надо гвоздь в спальне забить.
     
  6. eisernWolf

    eisernWolf Гость

    >>Ты, брат, тут не прав.

    Не прав, или ты со мной не согласен? :)

    >>Мне нужна рабочая, проверенная модель.

    А она и есть рабочая, и проверенная, т.к. построена на уже давно обкатанных паттернах, таких как например, Chain Of Responsibility.

    >>Не нужно буровой машины, если надо гвоздь в спальне забить.

    Вопли сишников давно ли утихли? :)

    >>Я не думаю, что появился паттерн, который решает те же проблемы что и Singleton.

    Я сам эту модель уже в двух проектах обкатал (после того, как хорошенько с ней сел и разобрался). Черт побери, решает! При этом еще и отсутствие жестких связей в качестве наследования сильно развязывает руки. В качестве проектов выступали пользовательские компоненты + полагающаяся инфраструктура. Единственный overhead - это необходимость все четко документировать. Но окупается сполна.
     
  7. Dr.Gigabit

    Dr.Gigabit Гость


    Модель сервисов и фабрик уже давно и успешно применяется в agile community, но совершенно по другим причинам, т.к. позволяет безболезненно подменять релизации для тестирования на моках/стабах.
     
  8. Electro

    Electro Гость

    Ув. NikSoft против твоего кода нечего не имею.
    Однако, открой MSDN и поищи там что связано
    с Singleton .
    Ну исп-й наздоровье статические перем.
    в своем типе для контроля кол-ва экземпляров.
    При чем тут remoting?
    Да и шаблоном это назвать наверное слишком?
     
  9. eisernWolf

    eisernWolf Гость

    А и вправду, причем тут Remoting??? Или это у тебя Singleton с Remoting-ом ассоциируется? :( Кстати, Singleton в принципе по задумке может создавать и больше одного экземпляра. Его основная задача - учет количества этих самых экземпляров. Причем как бы это ни смешно звучало, при помощи статического поля :)
     
  10. NikSoft

    NikSoft Гость

    Для: Electro
    А что тебя смущает?
     
  11. Electro

    Electro Гость

    Удивляет чья-то любовь к высокопарным из-рыганиям.
    Все бы ничего если-бы это непривадило к путанице:
    одна из заблудших:
    Посмотрим какие классы насл-т этот инт-с:
    HttpContext-Инкапсулирует все НТТР-сведения об индивидуальном НТТР-запросе.

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

    MarshalByValueComponent-Реализует объект IComponent и позволяет выполнить базовую реализацию для удаленных компонентов, которые размещаются в соответствии со значением (передается копия серийного объекта). и т.д.
    Это что не remoting?
    Активируемые сервером объекты — это объекты, временем жизни которых напрямую управляет сервер.И Singleton-один из типов этого объекта.
    И он один в любой момент времени
    Если экземпляр не существует, сервер создает экземпляр, который обслуживает все последующие клиентские запросы. Поскольку типы Singleton имеют время жизни по умолчанию, клиенты не всегда получают ссылку на один и тот же экземпляр класса удаленного взаимодействия, даже несмотря на то, что не бывает несколько экземпляров, доступных одновременно. И без всяких статич. перем.

    Обсуждать хитроперплетения DCOM,COM+ ,NET.Remoting
    в этой супер-статье,(супер шаблоне) ????

    А м.б. NikSoft=Pitc и смотри:
    http://codeby.net/forum/threads/10333.html
     
  12. eisernWolf

    eisernWolf Гость

    >>Посмотрим какие классы насл-т этот инт-с

    Уже смешно. Читаем дальше.

    >>Это что не remoting?

    :( Ты забыл упомянуть, что IServiceProvider (+ вся инфраструктура типа ISite и IComponent) разрабатывалсь для поддержки _дизайнера_. Еще раз возникает вопрос: причем тут Remoting?

    >>Активируемые сервером объекты

    :) :) :D Ты что кроме Remoting-a ничего в жизни не видел? Причем тут сервер, когда у нас и сервера-то может не быть?
     
  13. Electro

    Electro Гость

    Для много повидавшего,конечно строки из MSDN
    просто ничего незначат.
     
  14. eisernWolf

    eisernWolf Гость

    То Remoting, то "строки из MSDN"... Извини, я твои мысли не читаю :) А если уж на то пошло, то MSDN может служить лишь одним из источников знаний, но не как не истиной в последней инстанции.

    P.S. Еще раз уточню: Singleton не завязан на Remoting-e. Этот паттерн появился задолго до появления .NET даже в перспективе...
     
  15. Electro

    Electro Гость

    Так кидани примерчик.
    Посмотрим на твою версию.
     
  16. 62316e

    62316e Гость

    Как на счет многопоточности?
     
  17. NikSoft

    NikSoft Гость

    Модифицируем мой предыдущий пример для работы с несколькими потоками управления(threads).

    Код (Text):
    using System;

    namespace SerialPorts
    {
    sealed class SerialPort
    {
    static volatile int _instanceNumber;

    SerialPort() { }

    public static SerialPort NextInstance()
    {
    SerialPort serialPort;

    if (_instanceNumber > 1)
    {
    throw new SerialPortException("No more than 2 serial ports allowed");
    }
    else
    {
    lock (typeof(SerialPort))
    {
    _instanceNumber++;
    Console.WriteLine(String.Format("Starting to work with serial port {0}", _instanceNumber));
    serialPort = new SerialPort();  
    }
    }

    return serialPort;
    }

    public class SerialPortException : Exception
    {
    public SerialPortException(string s) : base(s) { }
    }
    }
    }
    Введен модификатор доступа к классу “sealed”, что запрещает расширение класса. Код, создающий новый обьект типа SerialPort, помещен в критическую секцию. Поле
    _instanceNumber содержит спецификатор volatile, запрещая переупорядочивание
    сгенерированного кода с целью его оптимизации. Класс SerialPortException, реализующий
    исключение, теперь является подклассом класса SerialPort. Пример кода, использующий
    класс SerialPort, приводится ниже.

    Код (Text):
    namespace SerialPorts
    {
    class Program
    {
    static void Main(string[] args)
    {
    SerialPort serialPort1, serialPort2, serialPort3;

    try
    {
    serialPort1 = SerialPort.NextInstance();
    serialPort2 = SerialPort.NextInstance();
    serialPort3 = SerialPort.NextInstance();
    }
    catch (SerialPort.SerialPortException spe)
    {
    Console.WriteLine(spe.Message);
    }

    Console.ReadLine();
    }
    }
    }
    Как видно из кода, ссылка на обьект типа SerialPort, возвращается статической публичной функцией NextInstance.
     
  18. 62316e

    62316e Гость

    Не нравитса мне volatile - медленый вроди он. ИМХО. Разве инного пути нет?

    ПС. NextInstance() есть - А чистить за собой не надо?
    ППС. МС: Добавление слова lock ещё не значит что это тхрид-сейф.
     
  19. eisernWolf

    eisernWolf Гость

    >>Как на счет многопоточности?

    Проблемы те же.
     
  20. karlito

    karlito Гость

    Для: NikSoft
    Опять два. Ещё больше проблем твой код привнёс.
    Не так решается проблема многопоточности с Singleton.

    Поищи в Нете и загляни в книги, в который раз говорю. Не придумывай колеса.
     

Поделиться этой страницей