PDA

View Full Version : [JAVA]Oggetto visibile a tutti


MEMon
31-07-2006, 10:21
C'è un modo per creare un oggetto che è fisibile a tutte le classi?
Ho tante classi le quali hanno in comune un oggetto, ma non solo come tipo, cioè non hanno bisogno tutte di un "tipo" di oggetto, ma proprio dello stesso oggetto!
Quindi dovrei passarlo a tutte le classi attraverso il costruttore o con qualche metodo, ma diventerebbe lungo e incasina il codice secondo me, quindi mi chiedevo se non ci fosse un metodo per istanziare un oggetto visibile ad alcune classi.

andbin
31-07-2006, 10:26
C'è un modo per creare un oggetto che è fisibile a tutte le classi?
Ho tante classi le quali hanno in comune un oggetto, ma non solo come tipo, cioè non hanno bisogno tutte di un "tipo" di oggetto, ma proprio dello stesso oggetto!
Quindi dovrei passarlo a tutte le classi attraverso il costruttore o con qualche metodo, ma diventerebbe lungo e incasina il codice secondo me, quindi mi chiedevo se non ci fosse un metodo per istanziare un oggetto visibile ad alcune classi.Non è forse molto bello dal punto di vista del design ma potresti fare una classe con dei campi public e static per tenere questi oggetti "globali".

MEMon
31-07-2006, 10:34
Intendi fare una cosa del genere?
public class OggettoGlobale{
static int val;

public static vois setVal(int x){
val=x;
}

public static int getVal(){
return val;
}
}
Ma poi se faccio OggettoGlobale.setVal(10); e in un altra classe faccio OggettoGlobale.getVal() mi ritrovo 10?

andbin
31-07-2006, 10:55
Intendi fare una cosa del genere?
public class OggettoGlobale{
static int val;

public static vois setVal(int x){
val=x;
}

public static int getVal(){
return val;
}
}
Ma poi se faccio OggettoGlobale.setVal(10); e in un altra classe faccio OggettoGlobale.getVal() mi ritrovo 10?Certo.

Visto che hai parlato di condividere degli oggetti, io però pensavo a una cosa del tipo:
public class OggettiGlobali
{
public static MioOggetto1 ogg1;
public static MioOggetto2 ogg2;
....

private OggettiGlobali () { } // classe non istanziabile
}

Gavrila
31-07-2006, 12:50
Che ne dici di questo?

public MyClass {
private MyClass instance;

private MyClass() {}

public MyClass getInstance() {
if (instance == null)
instance = new MyClass();
return instance;
}
}

MEMon
31-07-2006, 13:02
Da usare come?

andbin
31-07-2006, 13:08
public MyClass {
private MyClass instance;

private MyClass() {}

public MyClass getInstance() {
if (instance == null)
instance = new MyClass();
return instance;
}
}
Classico esempio di pattern "Singleton" ... ;)
Potrebbe anche andargli bene .. dipende da cosa, quella classe "in comune", deve fare.

EDIT: tra l'altro me ne sono accorto adesso ... il metodo getInstance deve essere static!!!

andbin
31-07-2006, 13:14
Da usare come?Ammesso di avere una classe:
public class OggettoComune {
private static OggettoComune instance;

private OggettoComune () {}

public static OggettoComune getInstance() {
if (instance == null)
instance = new OggettoComune ();
return instance;
}
}ogni volta che ti serve quell'oggetto (in qualunque altra classe), fai:
OggettoComune oc = OggettoComune.getInstance();
...In pratica ottieni sempre la stessa ed unica istanza di OggettoComune.

EDIT: instance deve essere static!!

MEMon
31-07-2006, 13:15
Perfetto mi piace molto come cosa!
Grazie ragazzi

The3DProgrammer
31-07-2006, 13:37
be ma l'istanza di OggettoComune deve essere anche static...

andbin
31-07-2006, 13:39
be ma l'istanza di OggettoComune deve essere anche static...Sì, giustissimo. :doh:
Grazie della segnalazione!

Gavrila
31-07-2006, 16:12
ops gli static :D

shinya
31-07-2006, 19:37
Si e poi devi gestire la sincronizzazione se hai intenzione di usarla in ambiente multithread.

theClimber
31-07-2006, 20:04
Come alternativa, in ambiente multithread, puoi evitare la sincronizzazione del metodo getInstance(), inizializzando il campo statico durante il caricamento della classe. La specifica del linguaggio garantisce che la classe viene caricata una sola volta e quindi esiste un solo oggetto comune.


public class OggettoComune {
private static OggettoComune instance = new OggettoComune();

private OggettoComune () {}

public static OggettoComune getInstance() {
return instance;
}
}


Nota Avanzata: Le classi vengono caricate una sola volta per classloader. Quindi attenzione in applicazioni che usano classloader multipli, tipo J2EE!!

Ciao

cionci
31-07-2006, 20:09
Classico esempio di variabile globale...imho non è molto bello per la programmazione OO... il pattern Singleton è poi sconsigliato anche da Gamma & Co.

theClimber
31-07-2006, 20:10
...
Quindi dovrei passarlo a tutte le classi attraverso il costruttore o con qualche metodo, ma diventerebbe lungo e incasina il codice secondo me, ........

Anche questa e' una valida alternativa, nota come IoC (Inversion of control) e spesso permette di creare codice piu semplice e test-abile.

La creazione e l'assegnazione degli oggetti (tramite costruttore o metodi setXxxx) viene automatizzata usando dei framework tipo:
http://jakarta.apache.org/hivemind/
http://www.springframework.org/

Ciao

theClimber
31-07-2006, 20:25
Classico esempio di variabile globale...imho non è molto bello per la programmazione OO... il pattern Singleton è poi sconsigliato anche da Gamma & Co.

L'utilizzo originale del pattern era limitato a creare oggetti univoci per a accedere a entità fisicamente univoche (esempio: una classe che fa da façade ad un dispositivo fisico di cui esiste un solo oggetto fisico, come una singola porta o sottosistema HW).

Concordo che purtroppo la maggior parte delle volte viene usato come "variabile globale" e questo causa problemi, diventando una dipendenza aggiuntiva "nascosta" che rende piu' complesso fare test sulle classi che la usano.

Ciao