Паттерн Одиночка гарантирует что в любой момент времени существует только один экземпляр класса.
Если у класса вашего приложения должен существовать только один экземпляр, воспользуйтесь паттерном Одиночка.
Реализация паттерна Одиночка на языке C# использует приватный конструктор и статический метод в сочетании со статической переменной.
Паттерн Одиночка предоставляет глобальную точку доступа к этому экземпляру.
Давайте рассмотрим интересный пример, представим, что у нас имеется фабрика по производству шоколада, разделим логику на 3 части: добавить смесь, подогреть и разлить.
Суть проблемы в том, что если придет новый рабочий, и не знает в какой на данной момент находится стадия изготовления шоколада, то он может подогреть второй раз или попытаться разлить то чего нет.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Паттерн_Одиночка { public class ChocolateBoiler { private ChocolateBoiler() { empty = true; boiled = false; } private bool empty; private bool boiled; public bool IsEmpty() { return empty; } public bool IsBoiled() { return boiled; } public void Fill() { Console.WriteLine("Зашли"); if (IsEmpty()) { empty = false; boiled = false; Console.WriteLine("Запоняем нагреватель молочно шоколадной смесью"); } } public void Drain() { if (!IsEmpty()&&IsBoiled()) { empty = true; Console.WriteLine("Слить нагретое молоко и шоколад"); } } public void Boil() { if (!IsEmpty() && !IsBoiled()) { boiled = true; Console.WriteLine("Доводим содержимое до кипения"); } } //статичная переменная хранящая единственный экземпляр static volatile ChocolateBoiler uniqueInstance; public static ChocolateBoiler CreateTest() { if (uniqueInstance == null) { uniqueInstance = new ChocolateBoiler(); } return uniqueInstance; } } class Program { static void Main(string[] args) { ChocolateBoiler boiler = ChocolateBoiler.CreateTest(); Task.Run(boiler.Fill); Task.Run(boiler.Fill); Task.Run(boiler.Fill); Thread thread1 = new Thread(boiler.Fill); thread1.Start(); Thread thread2 = new Thread(boiler.Fill); thread2.Start(); boiler.Fill(); boiler.Fill(); boiler.Boil(); boiler.Drain(); boiler.Drain(); Console.ReadKey(); } } }
