Sablonul de proiectare Singleton

Prezentare

Sablonul de proiectare Singleton se utilizeaza atunci cand se doreste sa se controleze numarul de obiecte creeate de un anumit tip. De exemplu obiectele de tip Facade sunt in mod uzual Singelton pentru ca doar de un astfel de obiect este nevoie.

Un exemlu de clasa Singelton in librariile standard java este de exemplu clasa InetAddress folosita pentru a reprezenta o adresa de IP. Pentru a obtine un obiect de tip InetAddress se utilizeaza codul:

 InetAddress addr = InetAddress.getByName("127.0.0.1");

Pentru implementarea unui Singelton se declara toti constructorii privati. In acest fel se blocheaza mecanismul standard de construire a obiectelor folosind operatorul new deoarece, fiind privati, constructorii nu mai sunt accesibili din exteriorul clasei. In pasul doi se declara o variabila statica de tipul clasei. In final se implementeaza o metoda static de acces la variabila static, metoda care va controla si procesul de creeare a instantei.

NOTA: Exista dezbateri cu privire la sablonul de proiectare singleton in ceea ce priveste utilitatea lui si daca este bine sa fie utilizat sau nu in construirea aplicatiilor. Cateva discutii aici, aici si aici.

Exemplu

Varianta 1

public class FileLogger {
 
    private static FileLogger logger;
 
// Prevent clients from using the constructor
    private FileLogger() {
    }
 
//Control the accessible (allowed) instances
    public static FileLogger getFileLogger() {
        if (logger == null) {
            logger = new FileLogger();
        }
        return logger;
    }
 
}

NOTA Varianta de mai sus nu este sigura intr-un mediu de lucru multi thread.

Varianta 2 - thread-safe

Pentru lucrul intr-un mediu mediu multithread - a aplicatia in care accesul la Singelton se face din mai multe threaduri - se poate utiliza varianta de mai jos.

public class SingletonDemo {
    private static volatile SingletonDemo instance = null;
    private SingletonDemo() { }
 
    public static SingletonDemo getInstance() {
    synchronized (SingletonDemo.class) {
                if (instance == null) {
                    instance = new SingletonDemo();
                }
            }
 
        return instance;
    }
}

Varianta 3 - enum

O a treia varianata de construire e aunui Singelton este prin utilizarea tipului java enum. Tipul enum este in mod implicit instantiat de Java o singura data (deci este singleton). Singelton-ul realizat folosind enum este sigur intr-un mediu multi thread.

public enum SingletonEnum {
 
    INSTANCE;
 
    public void doStuff() {
        System.out.println("Singleton using Enum");
    }
 
    public static void main(String[] args) {
        SingletonEnum.INSTANCE.doStuff();
    }
}