Singleton - cel mai simplu design pattern

Posted by anghelvalentin on September 01, 2019

Orice junior trebuie sa stie macar design patternul Singleton. Daca nu stii Singleton si nici variatiuni al acestuia, atunci ia-ti o cafea buna, fa liniste in camera si pune-te si citeste articolul asta.

Design patternurile sunt moduri de structurare a codului pentru a rezolva o problema generala in programare.

Din experienta mea am vazut ca cele mai folosite sunt: Singleton, Builder, Observable, Adapter si Factory

Primul design pattern pe care il invata toata lumea este Singleton. In anul 2 de facultate l-am invatat si de atunci nu l-am mai uitat, doar am invatat noi moduri de realizare a lui. Este foarte usor de creat si e si unul dintre cele mai folosite. 

Design patternul singleton il folosim cand vrem sa avem o singura instanta la nivelul aplicatiei. Un exemplu foarte bun este legat de conexiunea la baza de date. Nu vrem sa cream mai multe conexiuni catre baza de date din diferite parti ale aplicatiei. De aceea, am vrea o instanta care este share-uita la nivelul aplicatiei. Design patternul Singleton vine in ajutorul tau, cu o structura ce nu permite crearea mai multor instante.

Astazi iti voi prezenta doua moduri de creare: Simple Singleton  si Thread Safe Singleton

Simple Singleton

Pe asta il invata toata lumea, intrucat e cel mai simplu

internal sealed class SimpleSingleton : ISingletonSignature
   {
       private static SimpleSingleton _instace;
 
       private SimpleSingleton()
       {
 
       }
 
       public static SimpleSingleton GetInstance()
       {
           if (_instace == null)
           {
               _instace = new SimpleSingleton();
           }
           return _instace;
       }
 
       public void ShowMessage(string message)
       {
           Console.WriteLine(message);
       }
   }

Simplu nu inseamna si bun

Problema acestei implementari este cand intra in discutie si threadurile. Threadurile sunt misto, dar vin cu responsabilitati. Una dintre aceste responsabilitati este: shared condition. 

Exista posibilitatea ca doua threaduri sa intre fix in acelasi timp in :

if (_instace == null)

Si pentru ambele threaduri conditia de mai sus, sa fie adevarata. In acel moment, threadurile vor crea mai multe instante, lucru nedorit.

Thread Safe Singleton

internal class ThreadSafeSingleton : ISingletonSignature
   {
       private static ThreadSafeSingleton _instace;
       private static object padLock = new object();
 
       private ThreadSafeSingleton()
       {
       }
       public static ThreadSafeSingleton GetInstance()
       {
           lock (padLock)
           {
               if (_instace == null)
               {
                   _instace = new ThreadSafeSingleton();
               }
 
               return _instace;
           }
       }
 
       public void ShowMessage(string message)
       {
           Console.WriteLine(message);
       }
   }

Invata Thread Safe Singleton Tine minte un lucru: la interviuri cand esti intrebat de singleton, spune-le direct varianta thread safe. Seniorii chiar asta asteapta de la tine sa stii design patternul singleton care este thread safe.

Ce trebuie sa retii despre singleton: constructorul trebuie sa fie privat trebuie sa avem o instanta statica a obiectului chiar in interiorul clasei o metoda statica ce permite preluarea instantei statice, iar daca aceasta nu a fost creata, se face apelarea constructorului private mereu folosim thread safe singleton in aplicatiile MultiThreading

Source code