• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

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

  • Автор темы NikSoft
  • Дата начала
N

NikSoft

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

Код:
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 выдается сообщение
“Разрешено рабатать на более чем с двумя последовательными портами”.
Данный код легко модифицируется для конкретных нужд разработчика.
 
E

eisernWolf

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

Dr.Gigabit

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

eisernWolf

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

karlito

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

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

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

eisernWolf

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

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

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

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

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

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

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

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

Dr.Gigabit

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


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

Electro

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

eisernWolf

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

Electro

Для: Electro
А что тебя смущает?
Удивляет чья-то любовь к высокопарным из-рыганиям.
Все бы ничего если-бы это непривадило к путанице:
одна из заблудших:
Смысл в том, что если дизайн построен на сервисах, то синглтонов можно избежать (например, передавать сервис в контексте, т.е. наследнике IServiceProvider ). Сейчас эту модель Microsoft активно раскручивает в WCF: ...GetService<...>();
Посмотрим какие классы насл-т этот инт-с:
HttpContext-Инкапсулирует все НТТР-сведения об индивидуальном НТТР-запросе.

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

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

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

А м.б. NikSoft=Pitc и смотри:
https://codeby.net/threads/10333.html
 
E

eisernWolf

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

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

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

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

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

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

Electro

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

eisernWolf

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

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

Electro

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

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

NikSoft

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

Код:
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, приводится ниже.

Код:
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.
 
6

62316e

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

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

eisernWolf

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

Проблемы те же.
 
K

karlito

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

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

Обучение наступательной кибербезопасности в игровой форме. Начать игру!