Newsgroup: it.comp.java
Titolo: Variabili globali in java...

Ciao a tutti, sto creando un applicatione Mobile con NetBeans 5 Mobility. 
Avendo un'applicazione a più Form sapete come si fa ad avere una varibile 
(globale?) int  che posso read e write da qualsiasi punto dell'applicazione? 
Scusate la mia ignoranza in materia...
Esempio avendo due Form Form1 e Form2 in Form1 voglio assegnare un valore a 
questa varibile ed in Form2 vorrei leggerlo... Grazie anticipato per la 
risposta... 

lorcuci ha scritto:

soluzione non bella dal punto di vista dell'oop, ma funziona, potresti 
usare una variabile dichiarata public e static in una classe, tipo:
class GlobalVarContainer
{
   public static int variabile = 5;
   ...
}
per come dici tu sarebbe meglio che fosse un campo di form1 che viene 
settata da quest'ultima e letta da form2 mediante un metodo tipo 
getForm1FamousConstant(). Classico scambio di messaggi tra oggetti
-- 
         orsacchiotto.stupidotto
------------------------------------------
del resto il mio nick giustifica ogni cosa
        io abbia scritto o detto

 dell'applicazione?
Utilizza il pattern Singleton, serve a questo.
Ciao
Marco 

napo ha scritto:

ah ma dai pensavo servisse per creare classi dovessero essere 
instanziate una e una volta sola...


 (globale?) int  che posso read e write da qualsiasi punto dell'applicazione? 
public static int var;
In una qualsiasi classe.
PS: veramente una pessima idea.

 una e una volta sola...
E nel momento in cui ne hai una ed una sola all'interno dell'applicazione, 
puoi accedere ai suoi metodi ovunque. Quindi è come avere una variabile 
globale.
Ciao
Marco 

 
tiri in ballo un pattern per il compito sbagliato secondo me.


> 
os> tiri in ballo un pattern per il compito sbagliato secondo me.
Non credo. E' vero che va conservato  solo un intero e la cosa la puoi
fare benissimo con  una costante (aka static final), ma  č il caso che
quella classe sia istanziata piů volte ?
D'altro canto  se quella costante  č logicamente legata ad  una classe
del  progetto, beh,  allora mettere  la costante  in quella  classe fa
risparmiare qualche byte di bytecode, e la cosa probabilmente ha senso
in una applicazione come quella in esame.
-- 
 /\            ___
/___/\__|_|\_|__|___Gian Uberto Lauri_____________________
  //--\ | | \|  |   Integralista GNUslamico  
\/		    e allevatore di bug da competizione

Grazie per le risposte... All'inizio io ho aggiunto una proprietà int 
attraverso Bean Patterns al progetto vengono aggiunti due metodi di accesso 
SetVar(int var); e GetVar() ma non mi trovo coi valori.
Esempio: Form1 SetVar(5) da Form2 faccio il GetVar mi da 5. Poi torno 
indietro nella Form1 e la e faccio sempre come esempio SetVar(1) vado in 
Form2 faccio GetVar() e mi trovo sempre 5 non mi cambia più il valore... 
Come se parlassi di due varibili differenti.... Se non sono chiaro 
chiedetemi ulteriori informazioni. 

 globale.
Nient'affatto :-)
Il singleton è un pattern che si usa quando è necessaria *una* e *una*
*sola* istanza* di una classe, non un riferimento globale.
Dire che "è come avere una variabile globale" è riduttivo o più
semplicemente sbagliato.

> come avere una variabile globale.
VV> Nient'affatto :-) Il singleton è un pattern che si usa quando è
VV> necessaria *una* e *una* *sola* istanza* di una classe, non un
VV> riferimento globale.  Dire che "è come avere una variabile
VV> globale" è riduttivo o più semplicemente sbagliato.
Sorry Vincent,  ma la tua  definizione di Singleton manca  della parte
che riguarda il punto di accesso relativo a tale istanza.
Sono d'accordo  sul riduttivo, ma non  sullo sbagliato, a  meno che tu
non intenda  con "sbagliato" il  fatto che una variabile  globale (non
una "costante"(*) globale - che è quello che si ottiene con il pattern
Singleton) è anche scrivibile e non solo leggibile.
(*) E'  costante il riferimento all'oggetto, ma  lo stato dell'oggetto
può cambiare.


Che sia riduttivo sono d'accordo, ma anche dire "sbagliato" è secondo
me sbagliato! Singleton è usato PRINCIPALMENTE per avere una singola
istanza della classe in oggetto come giustamente dici, ma è proprio e
anche per questo che essendo unica l'istanza di tale oggetto, ogni
cambiamento del suo stato è visibile ovunque a run time.
Banalmente:
package it.sysdata.test.singleton;
public class Application {
  private static Application _singleton = null;
  public static int val;
  private Application() {
  }
  public static Application getInstance() {
    if (_singleton == null) {
      _singleton = new Application();
    }
    return _singleton;
  }
  public int getVal() {
    return val;
  }
  public void setVal(int val) {
    Application.val = val;
  }
}
*****************************************************************
package it.sysdata.test.singleton;
public class Form1 {
  private Application app = Application.getInstance();
  public void setVal(int val){
    app.setVal(val);
  }
  public int getVal(){
    return app.getVal();
  }
}
*******************************************************************************
package it.sysdata.test.singleton;
/**
 15-feb-2006
 Form2.java
 @author Marcello Pillitu
 */
public class Form2 {
  private Application app = Application.getInstance();
  public void setVal(int val){
    app.setVal(val);
  }
  public int getVal(){
    return app.getVal();
  }
}
**************************************************************************
package it.sysdata.test.singleton;
public class Main {
  public static void main(String[] args) {
    Form1 form1 = new Form1();
    Form2 form2 = new Form2();
    form1.setVal(5);
    System.out.println("Form1 -> valore:" + form1.getVal());
    System.out.println("Form2 -> valore:" + form2.getVal());
    form2.setVal(54);
    System.out.println("Form1 -> valore:" + form1.getVal());
    System.out.println("Form2 -> valore:" + form2.getVal());
    form1.setVal(3);
    System.out.println("Form1 -> valore:" + form1.getVal());
    System.out.println("Form2 -> valore:" + form2.getVal());
  }
}
L'esecuzione del main produce quanto segue:
Form1 -> valore:5
Form2 -> valore:5
Form1 -> valore:54
Form2 -> valore:54
Form1 -> valore:3
Form2 -> valore:3
Application.val mantiene il suo stato, indipendentemente da chi sia
stato a modificarlo.
Dico cagate?

 cambiamento del suo stato è visibile ovunque a run time.
SBAGLIATO! la visibilità dipende dal modificatore della classe
------------------------
LA VEDONO SOLO LE CLASSI DEL PACCHETTO SINGLETON
  package it.sysdata.test.singleton;
  class Application {
    private static Application _singleton = null;
    public static int val;
    private Application() {
    }
    public static Application getInstance() {
      if (_singleton == null) {
        _singleton = new Application();
      }
      return _singleton;
    }
----------------------------
LA VEDONO LE CLASSI DEL PACCHETTO E LE CLASSI FUORI DAL PACCHETTO CHE LA 
"extend"-ONO
package it.sysdata.test.singleton;
  PROTECTED class Application {
    private static Application _singleton = null;
    public static int val;
    private Application() {
    }
    public static Application getInstance() {
      if (_singleton == null) {
        _singleton = new Application();
      }
      return _singleton;
    }
-----------------------------------
LA VEDONO TUTTI
package it.sysdata.test.singleton;
  PUBLIC class Application {
    private static Application _singleton = null;
    public static int val;
    private Application() {
    }
    public static Application getInstance() {
      if (_singleton == null) {
        _singleton = new Application();
      }
      return _singleton;
    }
ciao
Maurizio


Intendevo lo STATO dell'istanza è visibile a tutti, non la classe in
sè ... se Application stesse in package diversi deve quanto meno
essere public, ovviamente; comunque una dichiarazione diversa da public
implica che Application sia una inner class complicando la faccenda per
niente...
L'idea era che ogni classe che voglia usare Application e modificarne
(o leggerne) lo stato abbia un riferimento ad un UNICA sua istanza e ne
faccia quello che le pare.
Sono stato spiegato?

 Singleton) è anche scrivibile e non solo leggibile.
Anche costante globale? Veramente orrendo :-)
Vi devo rimandare allo studio dei design pattern.
Il singleton non serve a dare visibilità globale ad una istanza, cosa
che si può fare tranquillamente con una variabile/costante/proprietà
statica e pubblica. Il compito del singleton è garantire by design che
di una classe ci sia una sola istanza e (per dirla in parole spiccie)
non se ne possa avere due.
Vedi un esempio di singleton nelle API Java:
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html

 cambiamento del suo stato è visibile ovunque a run time.
Mi spiace insistere, non è per pignoleria ma è sostanziale.
Chi ha detto che un singleton è visibile ovunque a runtime? Lo posso
definire come inner class e limitarne la visibilità alla classe che lo
contiene.
Questo per dire che la visibilità è un aspetto relativo nella
definizione del singleton. naturalmente poi il suo utilizzo tipico è
quello che conosciamo, ma il pattern ha un preciso scopo di garantire
by design una certa soluzione che non è la visibilità.

 non se ne possa avere due.
come sopra...... :-D


> pattern Singleton) è anche scrivibile e non solo leggibile.
VV> Anche costante globale? Veramente orrendo :-) 
Apri  la mente  :).
("I think we're  responsible for stretching them, setting  them off in
new  directions, and  keeping fun  in the  house" -  Alan  j.  Perlis,
introduzione  a "Structures  and interpetation  of  computer programs-
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-3.html
)
Avere  una  e  una  sola   istanza  significa  che  il  riferimento  a
quell'oggetto è con ogni sempre lo stesso.
Se  il riferimento conservato  nel Singleton  è ad  un oggetto  la cui
validità  non  è  eterna  e  va rinnovato,  chiamate  successive  alla
getInstance() torneranno riferimenti  diversi (in quanto l'istanza non
più  valida viene  scartata e  quella valida  è  probabilmente altrove
nella memoria).
Ma se  l'istanza dell'oggetto custodito dal  Singleton è potenzialmene
eterna, allora è una costante, ed ha simpatici usi (vedi oltre).
Certo,  non si  usa  il  Singleton del  manuale,  c'è qualche  piccolo
cambiamento   da   fare-   Ad   esempio,  usare   una   "getInstance()
sottointesa", che  in quei casi  la istanza -  o le istanze  - possono
essere create senza problemi in fase di caricamento della classe)
VV> Vi devo rimandare
VV> allo studio dei design pattern.
Attento a  non essere tu a  finire a rifare  fondamenti di informatica
1... :) :) :) :)
VV> Il compito del singleton è garantire by design che di
VV> una classe ci sia una sola istanza e (per dirla in parole spiccie)
VV> non se ne possa avere due.
VV> Vedi un esempio di singleton nelle API Java:
VV> 
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Runtime.html
Ti  devo per caso  rimandare a  quella documentazione  di Sun  dove ti
mostrano  come  creare  un  tipo  che può  assumere  solo  un  insieme
determinato  di valori  (roba vecchiotta,  dei tempi  java 1.3  se non
ricordo  male) ?  Quando  lo lessi  mi  permise di  dare una  ripulita
all'implementazione della cosa che avevo fatto io...
Con Java  1.5 la cosa non è  più indispensabile, ci sono  gli enum che
sono insufficienti una volta su qualche miliardo o meno.
Ma quando non c'erano, avevi  fior di librerie con costanti simboliche
il cui tipo era int. E qui  ti perdevi la cosa bella di Java che erano
i caragnamenti a  compile time: 
se tu hai una libreria di terze parti dove un parametro di un metodo X
può avere valori solo in  un piccolo sottoinsieme degli interi, magari
non connesso  (i.e. i  tipi dei  dati in una  tabella in  un DB)  e il
fornitore non ha  messo un test di validità  all'interno del metodo X,
con probabilità 1 ti saresti trovato  con gente che scrive i numeri in
literal (che  tanto li  sa e  sono più brevi  da scrivere).  Salvo poi
sbagliare  una cifra  e  sai il  tempo  perso per  trovare l'errore  a
runtime.
Se tu  dici che certa gente sarebbe  da mettere al muro,  hai tutte le
ragioni. Purtroppo  non ho  la possibilità di  mandare al  muro quella
gente, devo casomai "difendere" il mio codice da loro. 
E quindi  il parametro di  quel metodo  X non sarà  un int ma  di tipo
TiPoChePiaceAGianENonRompeteLeToe,  ed   i  valori  possibili  (uniche
istanze  degli  oggetti create  e  creabili)  con  nomi ben  chiari  e
significativi -scrivi, maledetto pigro, scrivi!-.
That's all folks.


 class and provide a global access point to it".
Come vedi la Gof stessa definisce gli intenti di singleton in entrambi
i modi:
- Unica istanza
- Accesso globale ad essa
Che senso avrebbe una istanza unica se non vi posso
accedere/controllarne lo stato/modificarne lo stato!?
Quindi mi permetto anche io di insistere, proprio perchè l'istanza è
UNICA uno degli usi che se ne può fare è per risolvere il problema
posto da lorcuci (ma questo NON significa che sia l'unico modo). NON è
errato usare un singleton nel suo caso.
Come si legge in giro, infatti:
*******************************
[...] So why would this be useful? Often in designing a system, we want
to control how an object is used, and prevent others (ourselves
included) from making copies of it or creating new instances. For
example, a central configuration object that stores setup information
should have one and one only instance - a global copy accessible from
any part of the application, including any threads that are running.
[...]
********************
[..]
Singleton
Il pattern creazionale Singleton è sicuramente uno dei più semplici
da applicare nell'ambito della programmazione ad oggetti. Esso si
può applicare ogni volta che nell'applicazione che si sta
sviluppando ci si trova di fronte ad una classe che modella un oggetto
il cui ruolo è unico, ha delle responsabilità speciali. In questo
caso si fa in modo che la classe abbia una sola istanza e
l'applicazione fornisca un punto di accesso globale ad essa. Ci sono
vari modi per costruire un oggetto che abbia un ruolo unico nel
sistema: indipendentemente da come si crea il singleton, comunque,
bisogna assicurarsi che non si possano creare nuove istanze della
classe. Per far ciò è sufficiente che la classe abbia un unico
costruttore con visibilità privata. La presenza di altri costruttori
non privati oppure la totale assenza di costruttori possono permettere
la creazione di molteplici istanze (in quest'ultimo caso il
compilatore aggiunge di default un costruttore vuoto con visibilità
pubblica). [...]
**************************
Il sigleton serve a:
    * Avere un accesso controllato all'unica istanza della classe
    * Avere uno spazio di nomi ridotto
    * Evitare la dichiarazione di variabili globali
    * Assicurarsi di avere un basso numero di oggetti utilizzati in
condivisione grazie al fatto che viene impedita la creazione di nuove
istanze ogni volta che si voglia utilizzare la stessa classe.
*******************
The Singleton design pattern addresses all of the previous paragraph's
concerns. With the Singleton design pattern you can:
    * Ensure that only one instance of a class is created
    * Provide a global point of access to the object
    * Allow multiple instances in the future without affecting a
singleton class's clients
************************
Singleton Pattern
The intent of the Singleton pattern as defined in Design Patterns is to
"ensure a class has only one instance, and provide a global point of
access to it".
What problem does this solve, or put another way, what is our
motivation to use it? In nearly every application, there is a need to
have an area from which to globally access and maintain some type of
data. There are also cases in object-oriented (OO) systems where there
should be only one class, or a predefined number of instances of a
class, running at any given time. For example, when a class is being
used to maintain an incremental counter, the simple counter class needs
to keep track of an integer value that is being used in multiple areas
of an application. The class needs to be able to increment this counter
as well as return the current value. For this situation, the desired
class behavior would be to have exactly one instance of a class that
maintains the integer and nothing more. 
Ciaooo

 Apri  la mente  :).
Si, ok, ho capito l'antifona ;)