Tämä artikkeli käsittelee ohjelmistotekniikan suunnittelumallia. Singleton käsittelee kaupunkia Australiassa

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ö muokkaa

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).[2]

Eager initialization (innokas alustus) muokkaa

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.[3] Voi heikentää suorituskykyä, jos luokka käyttää paljon resursseja.[2] 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) muokkaa

Luo esiintymän, vasta kun olio kutsutaan ohjelmassa. Tavallisin singletonin esiintymä. [4] 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ä.[3]

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

Kritiikki muokkaa

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ä.[5] Singletonien ajatellaan lisäävän moduulien keskinäistä riippuvuutta ja siten vaikeuttavan yksikkötestejä.[6]

Lähteet muokkaa

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

Viitteet muokkaa

  1. STL Singleton Template cc.byexamples.com. 9.6.2008. Arkistoitu 26.3.2018. Viitattu 26.3.2018.
  2. a b c Devin Soni: What is a Singleton? Medium. 31.7.2019. Viitattu 26.3.2023. (englanniksi)
  3. a b Java Singleton Design Pattern Best Practices with Examples | DigitalOcean www.digitalocean.com. Viitattu 26.3.2023. (englanniksi)
  4. 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).
  5. The singleton pattern: evil or just misused? Contentful. Viitattu 21.3.2023. (englanniksi)
  6. Why Singletons are Evil | Microsoft Docs web.archive.org. 15.7.2021. Arkistoitu 15.7.2021. Viitattu 21.3.2023.