3. Laboratorio
Definire :
• una classe PrintSpooler che:
PrintSpooler
– non ammette la contemporanea esistenza di due o più istanze;
– contiene il metodo void stampa(String msg)
• una classe con main(String[] arg) che tenta di ottenere il
riferimento a due istanze printSpooler in due istruzioni
consecutive
• I risultati visualizzati: C:jdk1.4binjava SingleSpooler
Opening one spooler
printer opened
Opening two spoolers
Only one spooler allowed
Ingegneria del Software - A.A. 2003/2004
4. Soluzione exception based
• Passo 1: la classe SingletonException
//new exception type for singleton classes
class SingletonException extends RuntimeException{
public SingletonException(){
super();
}
public SingletonException(String s){
super(s);
}
}
Ingegneria del Software - A.A. 2003/2004
5. Soluzione exception based
• Passo 2: la classe PrintSpooler
class PrintSpooler {
static boolean instance_flag=false; //true if 1 instance
public PrintSpooler() throws SingletonException {
if (instance_flag)throw
new SingletonException(“Only one spooler allowed");
else
instance_flag = true; //set flag for 1 instance
System.out.println("spooler opened");
}
public void finalize(){
instance_flag = false; //clear if destroyed
}
}
Ingegneria del Software - A.A. 2003/2004
6. Soluzione exception based
• Passo 3: la classe singleSpooler
public class SingleSpooler {
singleSpooler
static public void main(String argv[]){
PrintSpooler pr1, pr2;
System.out.println("Opening one spooler");
try {
pr1 = new PrintSpooler();
} catch(SingletonException e){…}
System.out.println("Opening two spoolers");
try {
pr2 = new PrintSpooler();
} catch(SingletonException e){…}
}
}
Ingegneria del Software - A.A. 2003/2004
7. Soluzione static class based
• Classe PrintSpooler con tutti i metodi statici
final class PrintSpooler {
static public void print(String s){
System.out.println(s);
}
}
StaticPrint
public class staticPrint {
public static void main(String argv[]){
PrintSpooler.print("here it is");
}
}
Ingegneria del Software - A.A. 2003/2004
8. Soluzione static method based
• Classe iSpooler con costruttore privato e metodo statico
class iSpooler {
static boolean instance_flag = false;
private iSpooler() { } Costruttore privato
static public iSpooler getInstance(){
if (! instance_flag){
instance_flag = true; Metodo statico
return new iSpooler();
} else return null;
}
public void finalize(){ instance_flag = false;}
}
Ingegneria del Software - A.A. 2003/2004
9. Confronto tra le soluzioni
• Osservazioni alla soluzione exception based
– Bisogna preoccuparsi di gestire le eccezioni
– Fortemente legata al mondo Java
– Rilascio “automatico” dello spooler non banale in Java
• Soluzione static class based
– Soluzione non scalabile
• Souzione static method based
– Rilascio “automatico” dello spooler non banale in Java (cfr.
funzionamento del Garbage Collector)
Ingegneria del Software - A.A. 2003/2004
11. Il pattern Singleton (1/5)
• Nome Singleton [GoF95]
• Synopsis Il pattern Singleton garantisce che sia possibile
creare una sola istanza della classe
• Context - Classi che dovrebbero avere esattamente un’
istanza
- Esempio:
Classe che assicura che non sia riprodotto
più di un brano musicale per volta.
Questa classe dovrebbe sospendere
l’esecuzione di un brano prima di iniziare a
riprodurre il successivo.
Ingegneria del Software - A.A. 2003/2004
12. Il pattern Singleton (2/5)
• Forces - Deve esistere esattamente un’istanza di una
classe
- L’unica istanza della classe deve essere
accessibile a tutti i client di quella classe
• Solution Una classe singleton ha:
- una variabile statica privata che contiene il
riferimento alla sua unica istanza
- i costruttori privati
- un metodo statico, tipicamente chiamato
getInstance o getClassname, che ritorna il
riferimento all’unica istanza
Ingegneria del Software - A.A. 2003/2004
13. Il pattern Singleton (3/5)
Da Context
a Solution
Ingegneria del Software - A.A. 2003/2004
14. Il pattern Singleton (4/5)
• Consequences
- Esiste esattamente un’istanza della classe
- Per ottenere il riferimento dell’istanza le classi
client devono invocare il metodo statico
getInstance e non usare il costruttore
- La specializzazione di una classe singleton è
scomoda e genera classi imperfette dal punto di
vista dell’incapsulamento. Problemi:
- classi con costruttori privati non
estendibili
- metodi statici non riscrivibili
Ingegneria del Software - A.A. 2003/2004
15. Il pattern Singleton (5/5)
• Implementation - Assicurarsi di dichiarare almeno un
costruttore privato
- Considerare il funzionamento del
garbage collector ed utilizzare
opportunamente il metodo finalize()
• Java API usage - La classe java.lang.Runtime è una
classe singleton (metodo statico
getRuntime())
• Code example - Esercizio: scrivere il codice dell’esempio
presentato in context
• Related Patterns - cfr. Abstract Factory, Builder, Prototype
Ingegneria del Software - A.A. 2003/2004