Паттерн Одиночка гарантирует что в любой момент времени существует только один экземпляр класса.
Если у класса вашего приложения должен существовать только один экземпляр, воспользуйтесь паттерном Одиночка.
Реализация паттерна Одиночка на языке 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();
}
}
}

