Singleton (Egyke)
Kategória: Létrehozási minta (Creational Pattern)
Lényege és célja
A Singleton minta célja, hogy garantálja: egy osztálynak egyetlen példánya létezik a teljes alkalmazásban, és ehhez a példányhoz egy globális hozzáférési pontot biztosít.
Gyakran használjuk olyan erőforrásoknál, amelyekből rendszerszinten csak egyre van szükség, vagy amelyek megosztása kritikus (pl. konfigurációs fájlok beolvasása, naplózó osztályok, vagy hardver-erőforrások kezelése).
A Singleton "szentháromsága" (Hogyan ismerjük fel?):
- Privát konstruktor: Megakadályozza, hogy külső kód a
newkulcsszóval új példányt hozzon létre. - Statikus mező: Ebben az osztályban tároljuk el az egyetlen létező példányt.
- Statikus getInstance() metódus: Ez az egyetlen út a példány eléréséhez. Ha még nem létezik, létrehozza, ha már létezik, visszadja a meglévőt.
Mikor használjuk?
- Amikor egy osztályból pontosan egy példányra van szükség az egész rendszerben.
- Amikor szigorúan kontrollálni kell a hozzáférést egy megosztott erőforráshoz.
- Amikor a globális változók használatát szeretnénk elkerülni, de szükség van egy közös elérési pontra.
Figyelem: A Singleton tesztelése (Unit Testing) nehézkes lehet, és néha "anti-pattern"-nek tekintik, ha túlzottan sok állapotot tárolunk benne, mert elrejti az osztályok közötti függőségeket.
Miért Java enum
Java-ban a Singleton gyakran enum-ként van megvalósítva, mert a JVM garantálja az egyetlen példány létrehozását. Az enum példányok az osztálybetöltés (class loading) során jönnek létre, ami a JVM specifikáció szerint szálbiztos, ezért nincs szükség külön szinkronizációra.
Fontos azonban, hogy ez csak a példány létrehozására igaz: ha az enum belső állapota módosítható (pl. mezőket változtatsz több szálról), akkor arról már neked kell gondoskodni (pl. synchronized, volatile, vagy egyéb konkurens megoldások).
Az enum további előnye, hogy védett a szerializációval szemben: deszerializáláskor a JVM nem hoz létre új példányt, hanem automatikusan a már létező enum konstansra hivatkozik vissza. Emellett reflektív úton sem példányosítható újra, így ezek a klasszikus Singleton-törési lehetőségek ki vannak zárva.
Mermaid Diagram
A diagram az osztály önmagára mutató kapcsolatát ábrázolja, ahol a statikus metódus és mező felel a példány kezeléséért.
classDiagram
class Singleton {
-instance: Singleton$
-Singleton()
+getInstance()$ Singleton
+doSomething() void
}
note for Singleton "A private konstruktor miatt\nkívülről nem hívható a 'new'"
Singleton --> Singleton : "tárolja az egyetlen példányt"