Одиночка (Singleton)

Шаблон Одиночка гарантирует создание единственного экземпляра объекта некоторого класса и предоставляет точку доступа для получения этого экземпляра. Существование единственного объекта часто требуется при организации доступа к аппаратному обеспечению, реализации кэша, систем ведения отладочной информации и т. п.

Общая схема шаблона достаточно проста (рис. 9). Конструктор класса объявляется закрытым – создавать объекты могут только методы самого класса. Для хранения единственного экземпляра используется закрытое статическое поле. Для получения экземпляра служит статический метод.

Рис. 9. Схема шаблона Одиночка.

Ниже представлен код, отвечающий описанной схеме шаблона Одиночка.

public sealed class Singleton

{

private static Singleton instance;

private Singleton()

{

}

public static Singleton GetInstance()

{

if (instance == null)

{

instance = new Singleton();

}

return instance;

}

}

Данная реализация шаблона имеет важный недостаток – она неустойчива в многопоточных приложениях. Перепишем пример с учётом этого:

public sealed class Singleton

{

private static Singleton instance;

private static readonly object Locker = new object();

private Singleton()

{

}

public static Singleton GetInstance()

{

lock (Locker)

{

return instance?? (instance = new Singleton());

}

}

}

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

public sealed class Singleton

{

private static readonly Singleton instance = new Singleton();

static Singleton()

{

}

private Singleton()

{

}

public static Singleton GetInstance()

{

return instance;

}

}

Следующая вариант реализации использует для отложенной потокобезопасной инициализации стандартный класс System.Lazy<T>, представленный в платформе.NET четвёртой версии.

public sealed class Singleton

{

private static readonly Lazy<Singleton> lazy =

new Lazy<Singleton>(() => new Singleton());

private Singleton()

{

}

public static Singleton Instance

{

get { return lazy.Value; }

}

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: