Patterns. Паттерн Singleton (Одинак). Особливості реалізації на C#

Паттерн Singleton (Одинак). Особливості реалізації на C#

Дана тема є продовженням теми:


Зміст


Пошук на інших ресурсах:




1. Структура паттерну Singleton. Рисунок

Структура паттерну Singleton зображена на рисунку 1.

 

Структура паттерну Singleton

Рисунок 1. Структура паттерну Singleton

 

2. Структура паттерну Singleton з прив’язкою до коду C#. Рисунок з поясненням

 

Структура паттерну Singleton. Приклад на C#

Рисунок 2. Структура паттерну Singleton. Приклад на C#

Екземпляр (об’єкт) класу Singleton отримується шляхом виклику методу Instance(). У методі Instance() відбувається створення екземпляру завдяки виклику конструктора класу в операторі new.

Оскільки конструктор класу Singleton реалізований з модифікатором доступу protected, то створити екземпляр цього класу з методів інших класів не вдасться. Однак, розширити можливості даного класу можна.

Якщо в задачі допускається можливість розширення класу-одинака успадкованими підкласами, то конструктор оголошується як protected. Якщо потрібно заборонити розширення класу-одинака, то конструктор повинен бути оголошений як private.

 

3. Текст програми на C#, який реалізує паттерн Singleton

 

using System;
using static System.Console;

namespace ConsoleApp9
{
  // Реалізація паттерну Singleton - Одиночка
  class Singleton
  {
    // Статичний метод, який повертає екземпляр класу Singleton.
    // Даний метод може бути замінений відповідною властивістю.
    public static Singleton Instance()
    {
      if (_instance == null)
      {
        _instance = new Singleton();
        return _instance;
      }
      else
      {
        return null;
      }
    }

    // Конструктор класу, оголошений як protected, для того щоб:
    // - заборонити створення екземпляру класу оператором new;
    // - можна було успадковувати даний клас.
    protected Singleton()
    {
    }

    // Статична внутрішня змінна, яка зберігає екземпляр класу.
    // До цієї змінної є доступ з методів даного класу
    // З методів інших класів доступу до змінної немає.
    private static Singleton _instance = null;

    // -------------------------------------------------
    // Інші внутрішні поля класу
    private int d;

    // Властивість для доступу до поля d
    public int D
    {
      get { return d; }
      set { d = value; }
    }

    // Метод, що виводить значення поля d
    public void Print(string text)
    {
      WriteLine("------------------");
      WriteLine("{0}. d = {1}", text, d);
    }
  }

  // Клас, що виступає клієнтом
  class Program
  {
    static void Main(string[] args)
    {
      // Це є код клієнта.
      // Створити єдиний екземпляр класу Singleton
      Singleton obj1 = Singleton.Instance();

      // Перевірити obj1 на рівність null
      if (obj1 != null)
      {
        obj1.D = 25;
        obj1.Print("obj1");
      }
      else
        WriteLine("obj1 == null");

      // Спроба створити другий екземпляр класу
      Singleton obj2 = Singleton.Instance();

      if (obj2 != null)
      {
        obj2.D = 77;
        obj2.Print("obj2");
      }
      else
        WriteLine("obj2 == null");
    }
  }
}

Результат виконання програми

------------------
obj1. d = 25
obj2 == null

 

4. Використання статичної властивості замість методу

Мова C# допускає використання властивостей замість методів. Тому, за бажанням, у вищенаведеному коді метод Instance() може бути замінений на властивість. Нижче наведено приклад оголошення такої властивості

// Статична властивість, яка повертає екземпляр класу Singleton
public static Singleton Instance
{
  get
  {
    if (_instance == null)
    {
      _instance = new Singleton();
      return _instance;
    }
    else
      return null;
  }
}

Використання властивості в методі клієнта може бути, наприклад, таким

...

// Це є код клієнта.
// Використати властивість Instance
Singleton obj1 = Singleton.Instance;

// Перевірити obj1 на рівність null
if (obj1 != null)
{
  obj1.D = 25;
  obj1.Print("obj1");
}
else
  WriteLine("obj1 == null");

// Спроба створити другий екземпляр класу
Singleton obj2 = Singleton.Instance;

if (obj2 != null)
{
  obj2.D = 77;
  obj2.Print("obj2");
}
else
  WriteLine("obj2 == null");

...

 


Зв’язані теми