Singleton

Singleton (ainokainen) on ohjelmistotekniikassa käytetty suunnittelumalli, jolla varmistetaan että luokasta tehdyllä oliolla on vain yksi instanssi, ja tarjoaa globaalin (ohjelman laajuisen) pääsyn siihen.

Singletonin esitys luokkakaaviossa.

Singleton-mallilla olevia etuja ovat muun muassa:

  • hallittu pääsy tietoon (kapselointi)
  • rajattu nimiavaruus ja näkyvyys (engl. scope) verrattuna globaaleihin muuttujiin

Mallin toteus riippuu käytetystä ohjelmointikielestä. Eräs C++:ssa käytetty tapa on toteuttaa Singleton-luokka template-mallin avulla.[1]

Käyttö

Singleton-luokalle tehdään yksityinen (private) konstruktori ja julkinen staattinen luokkametodi (tavallisesti nimetty getInstance()), joka palauttaa yksityiseksi luokkamuuttujaksi tallennetun instanssin.[2] Tämä takaa sen, että uutta oliota ei voida luoda, mutta kyseiseen instanssiin on globaali pääsy.

Singleton instanssin alustaminen voidaan toteuttaa kahdella tavalla: ennen luokan käyttöä (eager initialization, vapaa suomennos: innokas alustus) tai kutsuttaessa ensimmäisen kerran oliota getInstance()-metodilla (lazy initialization, vapaa suomennos: laiska alustus).[3]

Eager initialization (innokas alustus)

Luokan instanssi luodaan siinä vaiheessa, kun luokka alustetaan - ei siinä vaiheessa, kun sitä käytetään. Tämä voi aiheuttaa tarpeetonta resurssien käyttämistä, jos luokkaa ei käytetä kyseisessä ohjelman ajossa.[4] Voi heikentää suorituskykyä, jos luokka käyttää paljon resursseja.[5] Tämä alustus on kuitenkin säieturvallinen (thread-safe). Ei siis ole mahdollista, että erilliset säikeet saavat omia instanssejaan luokasta.

public class Singleton {
    // Alustetaan singleton-instanssi jo siinä vaiheessa, kun luodaan luokka
    private static final Singleton singleton = new Singleton();
    
    private Singleton() {
        // Yksityinen rakentaja, jotta ohjelmassa ei voida luoda uusia instansseja
    }
    
    // Julkinen luokkametodi, joka palauttaa luodun instanssin
    public static Singleton getInstance() {
        return singleton;
    }
    
    // ... luokalle tarpeellisia metodeja
}

Lazy initialization (laiska alustus)

Luo esiintymän, vasta kun olio kutsutaan ohjelmassa. Tavallisin singletonin esiintymä. [6] Aiheuttaa ongelmia monisäikeisissä (multi-threaded) järjestelmissä, koska jokainen säie saa oman instanssin.

public class Singleton {
    private static Singleton singleton = null;
    
    private Singleton() {
        // Yksityinen rakentaja
    }
    
    // Instanssin palauttava luokkametodi, jossa luodaan instanssi, kun sitä kutsutaan
    // ensimmäisen kerran ja palautetaan sama instanssi uudestaan kutsuttaessa
    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
    
    // ... luokalle tarpeellisia metodeja
}

Alustusta voidaan kuitenkin muokata säieturvalliseksi tekemällä getInstance()-metodista synkronoitu (synchronized) tai käyttämällä paremman suorituskyvyn mahdollistavaa double-checked locking -keinoa, joka on esitetty alla. Kahdella if-lauseella varmistetaan se, että luokasta on olemassa vain yksi ilmentymä.[7]

public static Singleton getInstance() {
    if (singleton == null) {
        synchronized (Singleton.class) {
            if (singleton == null) {
                singleton = new Singleton();
            }
        }
    }
    return singleton;
}

Kritiikki

Kriitikot eivät pidä singletonia suunnittelumallina, vaan ns. epäsuunnittelumallina. Syitä tähän on arveltu olevan mallin yksinkertaisuus ja väärinkäyttö osaamattomissa käsissä.[8] Singletonien ajatellaan lisäävän moduulien keskinäistä riippuvuutta ja siten vaikeuttavan yksikkötestejä.[9]

Lähteet

  • Gamma, Erich & Helm, Richard & Johnson, Ralph & Vlissides, John: Design Patterns, Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995. ISBN 0201633612.

Viitteet

  1. STL Singleton Template cc.byexamples.com. 9.6.2008. Arkistoitu 26.3.2018. Viitattu 26.3.2018.
  2. Devin Soni: What is a Singleton? Medium. 31.7.2019. Viitattu 26.3.2023. (englanniksi)
  3. Devin Soni: What is a Singleton? Medium. 31.7.2019. Viitattu 26.3.2023. (englanniksi)
  4. Java Singleton Design Pattern Best Practices with Examples | DigitalOcean www.digitalocean.com. Viitattu 26.3.2023. (englanniksi)
  5. Devin Soni: What is a Singleton? Medium. 31.7.2019. Viitattu 26.3.2023. (englanniksi)
  6. Krzysztof Stencel, Patrycja Węgrzynowicz: Implementation Variants of the Singleton Design Pattern, s. 396–406. Berlin, Heidelberg: Springer Berlin Heidelberg, 2008. ISBN 978-3-540-88874-1, 978-3-540-88875-8. Teoksen verkkoversio (viitattu 21.3.2023).
  7. Java Singleton Design Pattern Best Practices with Examples | DigitalOcean www.digitalocean.com. Viitattu 26.3.2023. (englanniksi)
  8. The singleton pattern: evil or just misused? Contentful. Viitattu 21.3.2023. (englanniksi)
  9. Why Singletons are Evil | Microsoft Docs web.archive.org. 15.7.2021. Arkistoitu 15.7.2021. Viitattu 21.3.2023.
    This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.