blah blah

Jug Marche




Home
Chi Siamo
Iscrizione
News
Lavoro
In evidenza
Eventi
Meetings
Convenzioni
Articoli
Tutorial
Jug Code
Jug Progetti
Altri Jug
Recensioni
Link Utili
Coordinamento

Pagine di Servizio:
Forum

Campagna Anti-IF



Design patterns in pillole: singleton pattern

introduzione
Chiunque scriva software avrà prima o poi sentito parlare o letto dei design pattern, una delle tematiche più discusse in ambito di progettazione del software negli ultimi anni.
Un design pattern, brevemente, può essere descritto così:
è una soluzione comprovata ad un problema di design ricorrente, che cattura l’essenza della soluzione a prescindere dal contesto applicativo, e per questo è riapplicabile in contesti diversi. Il pattern racchiude e formalizza una esperienza consolidata da altri sviluppatori rendendola comprensibile, e quindi trasmissibile, a tutti.
La prima collezione di queste “soluzioni comprovate a problemi ricorrenti” è stata raccolta da Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides anche noti come la Gang of Four (GoF) nel celebre libro “Design Patterns: Elements of Reusable Object-Oriented Software” nel 1995. Da allora il catalogo si è arricchito ed esteso anche ad altri ambiti, generando cataloghi di pattern specifici come per le architetture web e il real-time computing, ma i patterns descritti dalla GoF rimangono tuttora la base fondamentale della letteratura in merito.
Il movimento di ricerca e analisi di pattern nel mare magnum delle esperienze quotidiane dei programmatori ha parallelamente condotto anche alla definizione di soluzioni ricorrenti ma sbagliate, i cosiddetti antipattern, tutt’altro che rari da incontrare.
La ragion d’essere dei pattern è nel titolo dell’opera della GoF, “Reusable Object-Oriented Software” cioè nella riusabilità, nell’evitare di reinventare la ruota, non tanto nel codice ma nelle idee risolutive. “Object-Oriented” perché i patterns sfruttano appieno le caratteristiche dei linguaggi OOP e possono essere efficacemente implementati con questi.
Il catalogo originale di patterns definito dal GoF introduce anche una suddivisione differenziando i patterns in
-Strutturali: sono quelli riguardanti la composizione di classi e oggetti per ottenere strutture complesse
-Creazionali: riguardano le strategie di creazione degli oggetti, astraendone il processo di instanziamento
-Comportamentali: descrivono come le classi/oggetti interagiscono tra di loro e come vengono assegnate le responsabilità.
Passiamo di seguito ad analizzare uno dei più noti pattern creazionali, il singleton

Il Singleton pattern
Scopo: fare in modo che di una classe esista solo una istanza e fornire un solo punto di accesso ad essa, impedendo che sia possibile istanziarne diverse copie.

Motivazione: esistono delle situazioni in cui di una classe deve esistere una sola istanza, accessibile in modo uniforme a tutti.

Benefici:
-l’accesso all’istanza è controllato
-è possibile consentire più istanze, sempre in modo controllato

Gli elementi caratteristici fondamentali per l'implementazione di questo pattern sono due: un costruttore privato, per evitare che la classe possa essere istanziata arbitrariamente, e un metodo statico per accedere alla singola istanza.
Vediamo un esempio di classe che implementa il pattern:


public class Singleton {
   //l’istanza unica da rendere pubblica
   private static Singleton instance = null;
   //un dato membro da utilizzare tramite gli accessori
   private String aValue;
   //il costruttore, privato!!   
   private Singleton() {
     
   }
  //l’interfaccia unica per accedere alla sola istanza permessa
   public static Singleton getInstance() {
      if(instance == null) {
        instance = new Singleton();  //se non esiste, l'istanza viene creata (lazy loading o lazy instantiation)
      }
      return instance;  
   }
   // accessori al dato membro
   public void setAvalue(String value) {
     this.aValue = value;       
   }

   public String getAvalue() {
     return this.aValue;        
   }
}


//un esempio di utilizzo
public class Test {
  public static void main(String[] args) {
    Singleton a = Singleton.getInstance();
    Singleton b = Singleton.getInstance();
    a.setAvalue("pippo");    //valorizzo a ma scrivo b
    //a e b sono la stessa istanza del singleton
    System.out.println("b.getAvalue:" + b.getAvalue());
    
    b.setAvalue("topolino")//valorizzo b ma scrivo a
    System.out.println("a.getAvalue:" + b.getAvalue());
  }
}


Il codice visto sopra ha però un punto debole: l'accesso concorrente alla creazione dell'istanza del singleton, che potrebbe
generare due istanze dell'oggetto. Per ovviare a questo problema, tipicamente si percorrono due strade:
la prima è rinunciare al lazy loading, e creare l'oggetto istanza al momento della dichiarazione


private static Singleton instance = new Singleton();


e questo è thread safe. La seconda è sincronizzare il codice che istanzia l'oggetto:


public class Singleton {
   //l’istanza unica da pubblicare
   private static Singleton instance = null;
   private static Object sinc = new Object()//oggetto usato per il lock dell'instanziazione
   //un dato membro da utilizzare tramite gli accessori
   private String aValue;
   //il costruttore, privato!   
   private Singleton() {
   
   }
  //l’interfaccia unica per accedere alla sola istanza
   public static Singleton getInstance() {
      if(instance == null) {
        synchronized(sinc){
          if(instance == nullinstance = new Singleton();  //notare il doppio controllo sullo stato dell'istanza
        }       
      }
      return instance;  
   }
   // accessori al dato membro
   public void setAvalue(String value) {
     this.aValue = value;       
   }

   public String getAvalue() {
     return this.aValue;        
   }
}


val la pena sottolineare che non è stato sincronizzato tutto il metodo, ma solo la porzione che istanzia (una sola volta) l'oggetto, per non aggiungere inutile overhead.
A completamento della "blindatura" del singleton è conveniente anche ridefinire il metodo clone(), magari facendogli sollevare una eccezione ad hoc.


Letture consigliate
Design Patterns: Elements of Reusable Object-Oriented Software di Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1995)
Core J2EE Patterns: Best Practices and Design Strategies, Second Edition di Deepak Alur, Dan Malks, John Crupi (2003)

Design patterns in pillole: singleton pattern è menzionato in: Articoli

VQWiki include un sistema di notifiche; tuttavia, tu non sei ancora iscritto.



VeryQuickWiki Version 2.7.8 | Admin



All contents copyright of the author. (C)2006.JUG Ancona and its members. Java and all Java based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Other trademarks are registered by respective owners.