Sobes.tech
Junior

Какво е патърнът за проектиране Singleton?

sobes.tech AI

Отговор от AI

Патърнът Singleton гарантира, че класът има само един екземпляр и предоставя глобална точка за достъп до него.

Използва се, когато е необходим единствен екземпляр на ресурс, например:

  • Мениджър на конфигурацията
  • Пул за връзки с базата данни
  • Логгер

Реализации:

  • Мързелива инициализация (Lazy Initialization): Екземплярът се създава при първия му достъп.

    public sealed class Singleton
    {
        private static Singleton? instance = null;
        private static readonly object lockObject = new object();
    
        private Singleton() { } // Частен конструктор
    
        public static Singleton Instance
        {
            get
            {
                // Проверка за null позволява избягване на блокиране в повечето случаи
                if (instance == null)
                {
                    // Блокиране за безопасност при многопоточност
                    lock (lockObject)
                    {
                        // Повторна проверка за null вътре в блокирането
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }
    
  • Статична инициализация (Eager Initialization): Екземплярът се създава при зареждане на класа.

    public sealed class Singleton
    {
        private static readonly Singleton instance = new Singleton();
    
        private Singleton() { } // Частен конструктор
    
        public static Singleton Instance
        {
            get
            {
                return instance;
            }
        }
    }
    

    Предимство: по подразбиране безопасност при многопоточност, по-лесна реализация. Недостатък: екземплярът се създава, дори ако не се използва.

  • Използване на Lazy<T>: .NET Framework предоставя вградена поддръжка за мързелива инициализация.

    public sealed class Singleton
    {
        private static readonly Lazy<Singleton> lazyInstance = new Lazy<Singleton>(() => new Singleton());
    
        private Singleton() { } // Частен конструктор
    
        public static Singleton Instance
        {
            get
            {
                return lazyInstance.Value;
            }
        }
    }
    

    Предимство: безопасност при многопоточност и мързелива инициализация директно от кутията, по-чист код.

Предимства на Singleton:

  • Контрол върху броя на екземплярите.
  • Глобална точка за достъп.
  • Мързелива инициализация (в някои реализации).

Недостатъци на Singleton:

  • Може да нарушава принципа за единствена отговорност.
  • Затруднява юнит тестовете.
  • Може да доведе до силна свързаност на кода.