Singleton
A Singleton fogalma
A Singleton olyan osztály, amelyből csak egyetlen példány hozható létre. A Singleton tipikus példái a statisztikus objektumok vagy az egyedi rendszerösszetevők. Azonban a Singleton osztályok nehezen tesztelhetők, hacsak nem definiáljuk a típust interfészként, és nem a megvalósítását definiáljuk.
Singleton létrehozása
Public static tag, amely final mező
A private konstruktor pontosan egyszer hívódik meg az Elvis példány inicializálásakor, és garantálja, hogy az egész rendszerben egyedi példány legyen. Ugyanakkor az AccessibleObject.setAccessible() segítségével a private konstruktor is meghívható, de ezt a visszaélést meg lehet akadályozni, ha a második objektum létrehozásakor kivételt dobunk.
- Előnyök
- Az API egyértelműen jelzi, hogy az osztály Singleton.
- Könnyű.
Public static metódusként biztosított statikus gyármetódus
A visszaélésen (reflexió) kívül ez a módszer is garantálja, hogy az egész rendszerben egyedi példány legyen. Csak a mezőt váltottuk private-ra, és a visszatérést statikus gyármetódus segítségével végeztük.
- Előnyök
- Az API módosítása nélkül a Singleton tulajdonságot fel lehet adni.
- Például a statikus gyármetódus a szálonként eltérő példányt adhat vissza.
- Ha szükséges, generikus Singleton gyármetódussá lehet alakítani.
- A statikus gyármetódus metódushivatkozását szolgáltatóként lehet használni.
- Például az Elvis::getInstance helyett Supplier<Elvis>-ként is használható.
- Az API módosítása nélkül a Singleton tulajdonságot fel lehet adni.
Ha a fenti előnyöket nem használjuk, akkor jobb az első módszert alkalmazni.
Enum típus használata
A legelőnyösebb módszer az enum típus használata. A két korábbi módszerrel szemben ellenállóbb a reflexiós támadásokkal szemben, és tisztább a kódja. Ezenkívül, ahogy később is látni fogjuk, a két korábbi módszernek az a hátránya, hogy további kódot kell hozzáadni a sorosításhoz.
Fontos megjegyezni, hogy a létrehozandó Singleton örökölhet interfészt, de nem örökölhet osztályt.
Figyelmeztetések a Singleton osztály sorosításakor
Ha a fenti módszerek egyikével (első vagy második) létrehozott Singleton osztályt sorosítjuk, akkor a Serializable implementálása mellett minden példánymezőt transient-ként kell deklarálni, és a readResolve() metódust felül kell írni.
Hozzászólások0