Singleton - wyjaśnienie czym jest

Zapewne zdarzyło Ci się już spotkać z tym słowem. Jeśli nie wiesz co to jest i do czego służy - ten artykuł jest dla Ciebie.

Singleton jest wzorcem projektowym, który ogranicza ilość możliwych instancji (kopii) klasy. Dzięki temu mamy globalny dostęp do obiektu tej klasy, który jest inicjalizowany tylko raz, podczas pierwszego użycia, w sposób niewidoczny dla programisty.

Do czego może nam się przydać?
Wyobraź sobie sytuację, gdy piszesz program, który umożliwia użytkownikowi zmianę jego wyglądu (np. rysujesz własny pasek tytułowy (title bar)). Program ma kilka okien, każde z nich musi wiedzieć z jakiego folderu ma odczytać grafiki, które ma użyć przy ładowaniu. Potrzebujesz do tego stworzyć klasę, która będzie przechowywała informację o ścieżce do folderu, z które mają być załadowane dane. Do tego właśnie przyda się singleton, dane w nim przechowywane będą widoczne w całym programie.

Jak więc stworzyć singleton?


C#
public class Singleton
{
 private static Singleton instance;

 public static Singleton Instance
 {
  get
  {
   if (instance == null)
    instance = new Singleton();
   return instance;
  }
 }
}
VB.NET
Public Class Singleton

    Private Shared _instance As Singleton

    Public Shared Property Instance As Singleton
        Get
            If _instance Is Nothing Then
                _instance = New Singleton()
            End If
            Return _instance
        End Get
        Set(value As Singleton)
        End Set
    End Property

End Class


Jak teraz skorzystać z takiego singletona?

C#
Singleton a = Singleton.Instance;
VB.NET
Dim a As Singleton = Singleton.Instance

Przykład użycia:
C#
    public class Path
    {
        // singleton zawierający instancję będącą intem
        private static int instance = new int();

        private static Path() { }

        public static int Instance
        {
            get
            {
                if (instance == null)
                    instance = new int();
                return instance;
            }
        }

    }

    class Program
    {
        static void Main(string[] args)
        {
            // pobieranie inta z singletonu
            int someNumber = Path.Instance;

            // przekazanie wartości 
            // z singletonu do funkcji
            Function(someNumber);

        }

        static void Function(int path)
        {
            // kod funkcji
        }
    }

W ten sposób możemy stworzyć prosty singleton i korzystać z niego w programie jednowątkowym. Jeśli jednak program działa na kilku wątkach, może zdarzyć się sytuacja, że oba wątki stworzą jego kopię. Aby temu zapobiec, singleton powinien być zaimplementowany w ten sposób:

C#
public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}
VB.NET
Public NotInheritable Class Singleton

    Private Shared ReadOnly _instance As Singleton

    Shared Sub New()
    End Sub

    Public Shared Property Instance As Singleton
        Get
            Return _instance
        End Get
        Set(value As Singleton)
        End Set
    End Property

End Class
Użycie w tym przypadku konstruktora statycznego sprawia, że można on być wywołany tylko raz w danej domenie (AppDomain). Dzięki temu jesteśmy zabezpieczeni przed przypadkowym stworzeniem innej instancji klasy.
Jeśli masz jakieś pytania do tego tematu, bądź coś dalej jest niejasne, zostaw komentarze.

Więcej na ten temat możesz przeczytać tutaj (ang.)

Komentarze

  1. Czym się różni singleton od zmiennej globalnej? I czemu w językach takich jak C++ zmienne globalne są piętnowane, a singletony akceptowane?

    OdpowiedzUsuń

Prześlij komentarz

Popularne posty z tego bloga

[C#, VB.NET] Wprowadzanie tylko liczb do TextBoxa

Caroline - player muzyczny ♪♫