Singleton
Proprietati
Tip: Creational
Nivel: Obiect
Scop
Īn sistem se afla o singura instanta a acestei clase. Celelalte clase din sistem au permisiunea sa acceseze respectiva instanta.
Introducere
Avem nevoie de un obiect global: unul care este accesibil de oriunde din sistem si care trebuie creat o singura data. Toate p 151s1810b 59;rtile aplicatiei trebuie sa fie apte sa foloseasca obiectul global, aceeasi unica instanta.
Exemplul din PIM este o lista istoric - o lista actiunilor pe care le-a intreprins utilizatorul īn timpul utilizarii aplicatiei.
Oricare dintre modulele aplicatiei foloseste acelasi obiect HistoryList pentru a adauga la el actiunile pe care utilizatorul le-a efectuat sau pentru a efectua operatiile inverse (undo).
O modalitate de a obtine aceasta functionalitate este sa se creeze un obiect global de catre aplicatia principala si apoi sa se transmita referinta la el spre orice alt obiect care ar avea nevoie de el. Desigur, ar putea fi foarte dificil de stabilit cum sa se transmita referinta si sa se stie dinainte care parti ale aplicatiei ar avea nevoie de obiect. Un alt dezavantaj este acela ca nu interzice unui alt obiect sa creeze o alta instanta a clasei obiectului global, īn exemplul nostru HistoryList
O alta modalitate de a crea valori globale recurge la variabile statice. Aplicatia contine mai multe obiecte statice īn interiorul unei clase si le acceseaza direct. Dezavantajele sunt urmatoarele:
un obiect static nu este suficient, deoarece el se creeaza īn momentul īncarcarii clasei si prin urmare nu da posibilitatea sa i se transmita date īnainte de instantiere
nu exista nici un control asupra celor care acceseaza obiectul. Orice clasa poate accesa o instanta statica disponibila public.
daca realizati ca singletonul ar trebui sa fie, sa zicem, o treime, veti fi confruntat cu modificarea integrala a codului client.
Īn acest moment intra īn scena sablonul Singleton. El ofera un acces facil al īntregii aplicatii la obiectul global.
Aplicabilitate
sablonul Singleton se foloseste cānd se lucreaza cu o singura instanta a unei clase, care trebuie sa fie disponibila oriunde īn aplicatie.
Descriere
sablonul Singleton asigura ca maximum o instanta este creata de JVM (din acest motiv este numit singleton). Pentru a garanta controlul asupra instantierii, constructorul este facut privat.
Aceasta ridica o problema: este imposibil sa se creeze o instanta, prin urmare se furnizeaza o metoda accesor printr-o metoda statica (getInstance()). Aceasta metoda creeaza o singura instanta, daca ea nu exista deja, si returneaza referinta la respectiva instanta (singleton) catre apelantul metodei. Referinta la singleton este memorata ca atribut privat static al clasei singleton pentru rezolvarea apelurilor ulterioare.
Cu toate ca metoda accesor poate crea singletonul, īn majoritatea cazurilor acesta este creat la īncarcarea clasei.
Amānarea construirii este necesara numai daca trebuie facuta o anumita initializare īnainte de instantierea singletonului.
Un exemplu de singleton este presedintele SUA. La orice moment de timp trebuie sa existe numai un presedinte. Cānd presedintele Rusiei ridica telefonul rosu, el asteapta sa obtina legatura cu presedintele īn exercitiu al SUA.
Implementare
Diagrama de clase a sablonului Singleton este prezentata īn Figura 1.6
Figura 1.6. Diagrama de clase a sablonului Singleton
Pentru implementarea sablonului Singleton, este nevoie de:
Singleton - Are un constructor privat, mentine referinta privata si statica la unica instanta a clasei si poseda o metoda accesor statica care returneaza o referinta la instanta unica.
Restul implementarii clasei Singleton este normal. Metoda accesor statica poate lua decizii despre ce fel de instanta sa se creeze, pe baza proprietatilor sistem sau a parametrilor sai de intrare (vezi si sectiunea Variatiuni la acest sablon
Avantaje si dezavantaje
Avantaje
Singleton este singura clasa care poate crea o instanta a sa. Singura modalitate de creare este prin apelarea metodei statice oferita de ea.
Referinta nu trebuie transmisa tuturor obiectelor interesate. Fiecare obiect ce are nevoie de Singleton va apela metoda statica.
Dezavantaje
sablonul Singleton poate provoca probleme de threading, ce depind de implementare. Trebuie controlata cu atentie initializarea singletonului īntr-o aplicatie multithreading. Fara un control adecvat, aplicatia va beneficia de "razboaie ale firelor de executie".
Variatiuni la acest sablon
Variantele la acest sablon sunt cel putin urmatoarele:
Frecvent se considera optiunea de a avea mai multe instante īn interiorul clasei. Avantajul este ca restul aplicatiei nu se modifica, iar acele parti care sunt avizate de instantele multiple pot folosi alte metode pentru a le obtine.
Metoda accesor a clasei Singleton poate fi punctul de intrare īntr-o multime de instante, fiecare de alt subtip. Metoda accesor poate determina la executie instanta carui subtip sa fie returnata. Acest lucru este foarte util cānd se foloseste īncarcarea dinamica a claselor. Sistemul care foloseste obiectul Singleton poate ramāne neschimbat, pe cānd implementarile specifice ale Singleton-ului pot sa difere.
sabloane īnrudite
Abstract Factory
Builder
Prototype
Exemplu
Utilizatorii aplicatiei doresc sa aiba posibilitatea sa refaca comenzile precedente. Pentru a furniza aceasta functionalitate este nevoie de o lista istoric. Aceasta lista trebuie sa fie accesibila de oriunde din PIM si este nevoie de o singura instanta a sa.
Prin urmare, lista istoric este un candidat perfect pentru sablonul Singleton.
Exemplul 1 HistoryList.java
1. import java.util.ArrayList;
2. import java.util.Collections;
3. import java.util.List;
4. public class HistoryList
public static HistoryList getInstance()
public void addCommand(String command)
public Object undoCommand()
public String toString()
return result.toString();
}
Clasa HistoryList pastreaza o referinta statica la o instanta a sa, are un constructor privat si foloseste o metoda statica, getInstance pentru a furniza (referinta la) unicul obiect lista istoric la oricare dintre partile PIM. Variabila aditionala din HistoryList history, este un obiect List folosit pentru a pastra string-urile linii de comanda. Clasa HistoryList are doua metode, addCommand si undoCommand pentru adaugarea si stegerea de comenzi din lista.
|