PDA

View Full Version : [JAVA] Mi server un consiglio


DigitalKiller
23-05-2006, 16:00
Ragazzi ho bisogno di un consiglio!
All'interno di un programma ho classe Constant in cui sono definite tutte le impostazioni.
Questa è una parte della classe:

public class Constant {
public final static String constant1 = "xxx";
public final static String constant2 = "yyy";
.....
}


Ora ho la necessità di salvare queste impostazioni in un file di testo (unico per utente). Mi potreste dire come affrontare questa cosa modificando il meno possibile il resto del programma?

franksisca
23-05-2006, 17:33
cerca di essere + chiaro.
Per salvare devi vedere la classe File e le classi Stream, al massimo se vuoi ti posto un pò di codice.

Angus
23-05-2006, 17:58
Un approccio diverso:

java.util.Properties (http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html)

è una classe vetusta ma il suo sporco lavoro lo fa.

DigitalKiller
23-05-2006, 18:02
cerca di essere + chiaro.
Per salvare devi vedere la classe File e le classi Stream, al massimo se vuoi ti posto un pò di codice.
...provo ad essere più chiaro...

Ho questa classe Constant che definisce tutte le impostazioni del programma. Così com'è strutturato però, il programma non permette all'utente la modifica di alcune impostazioni. Voglio dare, quindi, la possibilità di modificare queste impostazioni e, di conseguenza, di salvarle in un file.
Per aggiungere questa funzionalità al programma, come mi conviene procedere? Mi conviene utilizzare la classe java.util.prefs? O qualche altra tecnica?

luxorl
23-05-2006, 18:10
Ragazzi ho bisogno di un consiglio!
All'interno di un programma ho classe Constant in cui sono definite tutte le impostazioni.
Questa è una parte della classe:

public class Constant {
public final static String constant1 = "xxx";
public final static String constant2 = "yyy";
.....
}


Ora ho la necessità di salvare queste impostazioni in un file di testo (unico per utente). Mi potreste dire come affrontare questa cosa modificando il meno possibile il resto del programma?

EDIT: leggendo la tua seconda spiegazione ho capito che il problema è un altro

DigitalKiller
23-05-2006, 18:13
Un approccio diverso:

java.util.Properties (http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html)

è una classe vetusta ma il suo sporco lavoro lo fa.

Avevo già dato uno sguardo a quella classe, ma mi dà la possibilita di memorizzare le impostazioni per singolo utente? Cioè, mi crea un file per utente?

Spiego cosa avevo pensato di fare...Senza eseguire l'installazione del programma su tutti i pc della lan, avevo pensato di installarlo su un server linux, condividere la cartella di installazione e di eseguirlo sui pc prendendo come percorso questa cartella. Al programma, poi, passo come parametro il nome utente con cui vorrei memorizzare le impostazioni...
E' fattibile come cosa?

Angus
23-05-2006, 18:19
Avevo già dato uno sguardo a quella classe, ma mi dà la possibilita di memorizzare le impostazioni per singolo utente? Cioè, mi crea un file per utente?

Spiego cosa avevo pensato di fare...Senza eseguire l'installazione del programma su tutti i pc della lan, avevo pensato di installarlo su un server linux, condividere la cartella di installazione e di eseguirlo sui pc prendendo come percorso questa cartella. Al programma, poi, passo come parametro il nome utente con cui vorrei memorizzare le impostazioni...
E' fattibile come cosa?

Utilizzando la classe Properties puoi salvare le impostazioni nel tipico formato dei file .ini tipici della piattaforma Microsoft oppure in XML. Detto questo, puoi imporre che il file di impostazioni abbia lo stesso nome dell'utente e lo salvi insieme agli altri.

Oceans11
24-05-2006, 10:36
Un approccio diverso:

java.util.Properties (http://java.sun.com/j2se/1.5.0/docs/api/java/util/Properties.html)

è una classe vetusta ma il suo sporco lavoro lo fa.




http://java.sun.com/docs/books/tutorial/essential/attributes/properties.html

qua ci sta qualche suggerimento...l'ho già usata e funziona a dovere
praticamente puoi caricare le properties di default e poi sovrascriverle con quelle dell'utente!!!!!!ovviamente puoi usare percorsi diversi per quelle di default (ex: dentro la cartella del prog) e quelle dell'utente (dentro la cartella dell'utente)!!!!!!

PGI-Bis
24-05-2006, 10:54
Il package java.util.prefs citato è stato introdotto esattamente per lo scopo da te richiesto. Preferences include il meccanismo per immagazzinare e recuperare impostazioni associate all'utente corrente (Preferences.userRoot()).

Personalmente preferisco Properties perchè non mi piace sapere che un mio programma sta scrivendo qualcosa in un punto del sistema che devo ignorare e che quindi non posso documentare all'utente. Da questo punto di vista è molto più semplice usare un Properties che non un Preferences. Si tratta comunque di un "vezzo" personale essendo innegabile la maggiore idoneità di Preferences ad immagazzinare impostazioni di sistema.

Sia l'uno che l'altro approccio richiedono comunque consistenti modifiche al codice che hai già scritto. Intendo per consistenti almeno un intervento per ogni oggetto che ora usi i campi statici di Constants. Il significato di Constants infatti è:

"per le ciabatte di giosafatte, questi valori mai e poi mai saranno cambiati"

Ora quei valori possono cambiare e tu sei nei guai (metaforici e neppure troppo grandi, ma sempre "guai").

DigitalKiller
24-05-2006, 11:44
Nei post precedenti mi sono espresso male. La classe Constant mi serve per impostare i valori di default utili al funzionamento del programma (es. indirizzo del mail-server, username, password, ecc). Durante l'esecuzione del programma, questi valori non vengono modificati. Se l'utente, però, vuole aggiornare i suoi dati, deve avere la possibilità di salvare le nuove impostazioni. E' sbagliato come approccio?


Comunque, ora sta facendo dei tentativi con java.util.Properties. Ho scritto una nuova classe Settings che legge un valore da un file di testo..Ho anche modificato la classe Constant in questo modo:

public class Constant {

private final static Settings impostazioni = new Settings(Main.getNome());

public final static String EMAIL_SERVER = impostazioni.getValue("EmailServer");
.....
}


Per recuperare il nome utente ho dovuto fare in questo modo, anche se non so se è corretto :rolleyes: :

public class Main extends JFrame {
private static String nome;

.....

public static void main(String[] args) {
...
nome = args[0];
}

public static String getNome() {
return nome;
}
}


Che ve ne pare? :sofico:

DigitalKiller
24-05-2006, 20:11
:help:

PGI-Bis
25-05-2006, 20:59
Corretto e che ve ne pare: sono due domandone :D.

Corretto.

Dal punto di vista del linguaggio di programmazione Java è ineccepibile ma i linguaggi di programmazione possono fare ben poco per evitare che se ne faccia scempio.

E' anche possibile che il risultato coincida con le tue intenzioni: immagino che tu l'abbia provato e ne abbia avuto un riscontro positivo.

Diciamo allora che è corretto in quanto rispetta appieno le specifiche del linguaggio di programmazione Java e produce il risultato atteso.

Che ve ne pare.

Eh eh eh. Credo che la risposta dipenda dall'approccio alla programmazione di chi la voglia dare.

Ad esempio per me quello che hai scritto viola il principio di identità. Siccome per me il principio di identità è il muro portante dell'intera costruzione detta "orientamento agli oggetti" e ogni programma andrebbe "scritto" usando la prospettiva orientata agli oggetti, io non potrei che esprimere la stessa cosa in un modo diverso.

Probabilmente tu vedi le cose in modo diverso. Attestata questa diversità di punti di vista, direi che la prima cosa realmente importante è che quanto tu hai scritto e riportato nel messaggio sia coerente con il resto del tuo programma.

Detto altrimenti, se scrivi metà programma usando un certo orientamento agli oggetti, un quarto seguendo una prospettiva procedurale e un quarto usando quella funzionale potresti avere un problema di coerenza a meno che la diversità di prospettive non sia espressione di un'unica regola comune, più generale che le comprenda tutte e tre, esattamente per come sono state usate.

Per come la vedo io, la programmazione è un consapevole esercizio di semplicità.

In conseguenza di ciò non posso che dire che se quanto hai scritto ti appare semplice, secondo un'idea di semplicità di cui sei consapevole (cioè puoi spiegare perchè hai scelto una certa struttura al posto di un'altra nei termini della tua idea di semplicità) allora il tuo codice è corretto anche al di là delle mere ragioni del linguaggio Java, incidentalmente rispettate.

DigitalKiller
26-05-2006, 11:48
Corretto e che ve ne pare: sono due domandone :D.

Corretto.

Dal punto di vista del linguaggio di programmazione Java è ineccepibile ma i linguaggi di programmazione possono fare ben poco per evitare che se ne faccia scempio.

E' anche possibile che il risultato coincida con le tue intenzioni: immagino che tu l'abbia provato e ne abbia avuto un riscontro positivo.

Diciamo allora che è corretto in quanto rispetta appieno le specifiche del linguaggio di programmazione Java e produce il risultato atteso.

Che ve ne pare.

Eh eh eh. Credo che la risposta dipenda dall'approccio alla programmazione di chi la voglia dare.

Ad esempio per me quello che hai scritto viola il principio di identità. Siccome per me il principio di identità è il muro portante dell'intera costruzione detta "orientamento agli oggetti" e ogni programma andrebbe "scritto" usando la prospettiva orientata agli oggetti, io non potrei che esprimere la stessa cosa in un modo diverso.

Probabilmente tu vedi le cose in modo diverso. Attestata questa diversità di punti di vista, direi che la prima cosa realmente importante è che quanto tu hai scritto e riportato nel messaggio sia coerente con il resto del tuo programma.

Detto altrimenti, se scrivi metà programma usando un certo orientamento agli oggetti, un quarto seguendo una prospettiva procedurale e un quarto usando quella funzionale potresti avere un problema di coerenza a meno che la diversità di prospettive non sia espressione di un'unica regola comune, più generale che le comprenda tutte e tre, esattamente per come sono state usate.

Per come la vedo io, la programmazione è un consapevole esercizio di semplicità.

In conseguenza di ciò non posso che dire che se quanto hai scritto ti appare semplice, secondo un'idea di semplicità di cui sei consapevole (cioè puoi spiegare perchè hai scelto una certa struttura al posto di un'altra nei termini della tua idea di semplicità) allora il tuo codice è corretto anche al di là delle mere ragioni del linguaggio Java, incidentalmente rispettate.

Giusto per un confronto, tu come avresti fatto?

PGI-Bis
26-05-2006, 14:47
Normalmente risponderei con un codice che sia il più possibile in linea con quanto è comune in tema di orientamento agli oggetti: categorie, esemplari e la finta metafora del messaggio fintamente applicata.

Non per supponenza ma perchè non voglio correre il rischio di confondere le idee ad alcuno.

Faccio uno strappo alla regola perchè non si può stare sempre zitti (e non poteva risparmiarmi, penserai :D).

Supponiamo che Ciccio sia l'oggetto che voglia sapere, ad un certo punto della sia vita, il valore di una proprietà "user name".

Ecco come, in un programma vero (come si sul dire, in produzione), faccio e farei:

Ciccio (parziale)
private void quandoCiccioVuoleUserName() {
Comm getUserNameComm = new Comm(
new Sender("Ciccio"), //il mittente
new Addressee("SystemPropertiesManager"), //il destinatario
new Message(Language.GET_AS_STRING), //il messaggio
new Referent(Language.USER_NAME), //ciò di cui si parla
new Context(Language.VALUE_REQUEST)); //contesto del messaggio
sendComm(getUserNameComm);
}

//ciccio invia un messaggio attravero il canale "ambiente"
public void sendComm(Comm comm) {
if(environment != null) {
environment.handlComm(comm);
}
}

//ciccio.handleComm
public void handleComm(Comm comm) {
if(comm.getAddressee().equals("Ciccio")) {
if(comm.getContext() == Language.VALUE_ANSWER)) {
handleValueAnswerComm(comm);
}
}
}

//ciccio riceve il nome di un utente.
private void handleValueAnswerComm(Comm comm) {
if(comm.getReferent() == Language.USER_NAME) {
String userName = comm.getMessage().getContentAsString();
//Ciccio ottiene il nome utente
}
}

Per sapere il nome utente, Ciccio genera un atto di comunicazione (nel contesto di una richiesta di valore, riferita al nome utente, richiede una stringa). L'atto è propagato attraverso un canale (unico per ciccio), environment. E qui Ciccio finisce la sua comunicazione.

Nello stesso sistema potrebbe esistere un oggetto SystemPropertiesManager in grado di riconoscere un atto comunicativo del tipo generato da Ciccio.

SystemPropertiesManager (parziale)
public void handleComm(Comm comm) {
if(comm.getAddressee().equals("SystemPropertiesManager")) {
if(comm.getContext() == Language.VALUE_REQUEST) {
handleValueRequestComm(comm);
}
}
}

private void handleValueRequestComm(Comm comm) {
Object property = propertyMap.getValue(comm.getReferent()); //estrae USER_NAME
Comm propertyAnswerComm = new Comm(
new Sender("SystemPropertiesManager"),
new Addressee(comm.getSender().toString()),
new Message(property),
new Referent(Language.USER_NAME),
new Context(Language.VALUE_ANSWER));
sendComm(propertyAnswerComm);
}

private void sendComm(Comm comm) {
if(environment != null) {
environment.handleComm(comm);
}
}

Qui SystemPropertyManager semplicemente dichiara che se qualcuno gli stia parlando di richieste di valori e la discussione abbia ad oggetto il nome utente egli è in grado di "rispondere", generando un atto comunicativo che tratta di nome utente, nel contesto di una risposta ad una richiesta di valore, avente come messaggio il nome utente.

Il tutto può sembrare molto bizzarro ma non è affatto un'anomalia nei sistemi oggi esistenti (i message driven beans J2EE funzionano grazie ad una logica di questo tipo, i server http sono interpretabili in una prospettiva sostanzialmente simile a questa sebbene più essenziale).

Manca tutto il panorama in cui si trovano Ciccio e SystemPropertyManager. Molto brevemente, environment, il canale usato da Ciccio e SystemPropertyManager per la comunicazione, è poi una normalissima coda di propagazione asincrona di messaggi, salve alcune questioni relative alla generazione dei riferimenti ai vari oggetti correlati dal contesto (definisco il contesto come la minima relazione esistente tra due identità frutto della medesima percezione).

Ripeto comunque che alla fine della fiera conta solo il fatto che coerentemente ad una diversa interpretazione circa il come realizzare un programma io do una risposta diversa da quella che hai dato tu. E' chiaro che per me sia preferibile quella che do io e per te quella che dai tu, altrimenti saremmo entrambi affetti da personalità multipla: penso una cosa, ne dico un'altra e ne faccio una terza :D.

Angus
26-05-2006, 15:30
cuttone

Mi hai ricordato l'epica diatriba (http://www.oreilly.com/catalog/opensources/book/appa.html) microkernel vs kernel monolitico tra Tanenbaum e Torvalds... :old:

DigitalKiller
26-05-2006, 15:47
Super-mega-iper-cut


...detto questo...posso credo che abbandonerò la programmazione e che cambierò lavoro :nera: :sob:

PGI-Bis
26-05-2006, 16:20
Non eccepirò mai più alle mie regole :D.

Non credere che quello che ho scritto sia la verità assoluta. Anzi. Pensa che è tutto fondato su un unico pressuposto. Significa che se cade quello diventa tutto un arzigogolo senza arte nè parte. Come se non bastasse, non è un che di dimostrabile: l'identità è una definizione circolare (è identico ciò che esclusivamente uguale a sè stesso). Somiglia di più ad un'evidenza e le evidenze sono tali finchè qualcuno non creda diversamente.

DigitalKiller
28-05-2006, 11:56
Ho modificato un po' il codice in questo modo (abbandonando la classe Constant):

public class Main extends JFrame {

private Settings impostazioni;

public static void main(String[] args) {

.....

impostazioni = new Settings(args[0]);
....

}
.........

public Settings getPreferences() {

return impostazioni;
}
}


Poi, nelle classi in cui ho necessità di recuperare le impostazioni faccio in questo modo:


public class Class1 extends JFrame {

private Main main;
private Settings impostazioni;

public Class1(Main main) {
....
this.main = main;
this.impostazioni = main.getPreferences();
....
}
}


Ora va meglio (...o anche questa è una domandona :D )?

PGI-Bis
28-05-2006, 12:29
Non ho il termine di paragone precedente (il Class1 per come era prima).

Del codice che hai incollato posso dire che vedo chiaramente espressa un'identità (Class1).

Class1 rispetta il principio di identità ed il corollario dell'autonomia sebbene il costruttore Java richieda un argomento di tipo Main perchè in Java le classi esprimono anche relazioni.

Esplicitamente, Main è per Class1 la relazione che intercorre tra tutti gli oggetti (aka coloro che possiedono un'identità) che possano "getPreferences()", restituire un certo valore Settings, così come per Class1 Settings è la relazione che intercorre tra tutti gli oggetti che (presumo) possano "getUserName", restituire un certo valore userName.

Dico che è rispettato in Class1 il principio di autonomia in quanto l'autonomia opera tra identità diverse e non tra un'identità ed una relazione (tra identità).

Incidentalmente, in Java ogni "class" esprime una relazione ed eventualmente anche un'identità.

Per l'angolo della sciarada ( :D ) come esempio di "class" Java che non esprime un'identità possiamo invece prendere Main. Main è parte di un oggetto la cui definizione identica è data dalla somma delle definizioni di Main e Settings cosa facilmente rilevabile considerando l'ipotesi di una sostituzione di Settings con un "SubSettings": farlo richiederebbe infatti una conseguente modifica della definizione di Main (per via di quel "new Settings").