Visualizzazione dei risultati da 1 a 5 su 5
  1. #1

    Problema con gli oggetti

    In un esercizio sugli array mi si chiede:

    codice:
    Si scriva un programma Java che prenda in input un file contenente una sequenza
    di righe, ognuna contenente le informazioni relative ad un punteggio di giuoco, e
    costruisca la classifica dei primi cento punteggi ottenuti.
    Ogni riga del file contiene una sequenza di opzioni seguiti dai relativi valori.
    Le varie opzioni devo essere interpretate nel modo seguente:
    -nick: seguito da una stringa con il nickname del giocatore (è sempre presente).
    -p: seguito da un intero che indica il punteggio complessivo (è sempre presente).
    -a: seguito da un intero, indica l'età del giocatore.
    -i: seguito da una data, indica la data d'iscrizione del giocatore.
    -n: seguito da un intero, indica il numero di partite giocate dal giocatore.
    -u: seguito da un intero, indica l'ultimo punteggio ottenuto dal giocatore.
    -dp: seguito da una data, indica la data in cui è stato totalizzato il punteggio.
    -bonus: non seguito da alcun valore, indica che il giocatore ha un bonus.
    Tutte le righe finiscono con un punto e virgola preceduto da uno spazio.
    In caso di parimerito deve apparire per primo il giocatore che appare per prima nella
    lista di input.
    Specifiche
    Utilizzare un oggetto Builder per la costruzione degli oggetti contenuti nella
    classifica di giuoco. Gli oggetti contenuti nella classifica devono essere definiti come
    oggetti immutabili
    Utilizzare i metodi toString() per la descrizione degli oggetti.
    E ho un input in cui non sono sempre presenti le stesse informazioni per ogni giocatore.
    Eccone una parte:
    codice:
    -nick AFONTANA -p 7570 ;
    -nick LRICCI -p 8674 -u 5643 ;
    -nick AGIULIANI -p 6998 -nome Antonio GIULIANI -bonus ;
    -nick FDEANGELIS -p 2855 ;
    -nick DDEANGELIS -p 3659 -n 9098 ;
    -nick FGATTI -p 8464 -u 6141 ;
    -nick VPELLEGRINI -p 6404 -nome Valerio PELLEGRINI -u 1885 -a 23 -n 7219 -i 10/11/2009 -dp 18/5/2010 ;
    -nick AFERRARO -p 1695 -u 9558 -bonus ;
    -nick CRIVA -p 6624 -nome Camilla RIVA -u 6060 -bonus -i 20/5/2009 -dp 29/7/2010 ;
    -nick SMORETTI -p 1645 -dp 12/4/2010 ;
    -nick MBRUNO -p 8481 ;
    -nick NPELLEGRINI -p 7071 -nome Nicole PELLEGRINI ;
    -nick EFARINA -p 8140 -dp 11/9/2010 ;
    -nick GVALENTINI -p 3089 -i 15/11/2009 ;
    -nick LPALUMBO -p 6544 -u 6008 -n 7117 ;
    -nick FGALLO -p 7972 -u 5888 ;
    -nick EORLANDO -p 8058 -a 31 ;
    -nick GPIRAS -p 5813 -nome Gianluca PIRAS ;
    -nick ACAPUTO -p 4484 -nome Alex CAPUTO -dp 3/1/2010 ;
    -nick MGALLI -p 1269 -i 14/6/2009 ;
    -nick EBELLINI -p 5784 ;
    -nick AROSSETTI -p 1560 -n 9575 ;
    -nick PCONTE -p 8493 -dp 6/4/2010 ;
    -nick AMONTANARI -p 4342 ;
    Il dubbio era su come trasformare le stringhe del testo in oggetti, e come fare dato che ogni stringa presenta valori differenti, avrei costruttori diversi, ma l'ordine dei parametri è disordinato, quindi non potrei utilizzare nemmeno i costruttori telescopici.
    Forse con la classe Scanner bisogna leggera ogni singola stringa e vedere se è presente, e nel costruttore si assegna quel valore per il nick per esempio, altrimenti gestisco un' eccezione.
    L'idea che ho pensato è questa ma non saprei realizzarla concretamente, potreste guidarmi...?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Problema con gli oggetti

    Originariamente inviato da Darèios89
    Il dubbio era su come trasformare le stringhe del testo in oggetti
    La prima questione è sicuramente quella di stabilire come "modellare" in termini OOP queste informazioni.
    E nel testo ci sono diversi indizi. Intanto parla di "righe", dicendo che ognuna descrive un "punteggio di gioco". E poi mostra l'elenco delle opzioni presenti in una riga.

    Quindi mi pare subito intuitivo che si può logicamente definire una classe es. PunteggioGioco (nome che puoi cambiare/scegliere tu a piacere, purché sensato, se il mio non ti piace) e che contiene i campi che poi andranno a rappresentare lo "stato" di un oggetto.

    Come "modellare" poi queste singole informazioni è un altro discorso. Per 'nick' un String mi pare ovvio, come pure sembra logico usare un int per 'punteggio complessivo', 'età', 'numero di partite' e 'ultimo punteggio'.

    Per le due date la cosa diventa più dubbia. Si potrebbe usare un java.util.Date o un java.util.Calendar/GregorianCalendar o ancora una "tua" classe es. Data che modella le varie informazioni. Ma dipende molto da chi/come/dove saranno usate queste date.

    Per il 'bonus' pare di capire che è un "c'è" o "non c'è", quindi un boolean true/false mi pare più che appropriato.

    Dal momento poi che il testo dice di realizzare oggetti "immutabili", allora questa classe avrà solo metodi "getter" per l'accesso alle proprietà (a parte metodi di uso generale come toString() o eventualmente equals()/hashCode() o altro).

    Originariamente inviato da Darèios89
    quindi non potrei utilizzare nemmeno i costruttori telescopici.
    I costruttori per così dire "telescopici" (termine che tra l'altro è molto informale e poco usato/sentito) sono quelli in cui più costruttori sono simili tra di loro e ognuno aggiunge "qualcosa" in più (tipicamente 1 parametro) rispetto ad un altro.
    Questo andrebbe bene se si vuole offrire una certa flessibilità per un uso diretto e arbitrario dei costruttori da parte di un programmatore. Ma qui c'è una necessità molto specifica: non è il programmatore che sceglie quale costruttore usare!! Perché il tutto è "pilotato" da dei dati.
    Quindi i costruttori "telescopici" mettiamoli un po' da parte.

    Nel testo c'è un'altra indicazione importante: "Utilizzare un oggetto Builder per la costruzione degli oggetti".

    Joshua Bloch nel suo libro "Effective Java" 2a edizione, nell'item 2 "Consider a builder when faced with many constructor parameters" parla proprio di questo.

    I costruttori telescopici tecnicamente sono ok ma possono risultare poco comprensibili nel punto dove poi si usano. Perché è ovvio che chi legge la espressione della istanziazione dovrebbe cercare di capire quale costruttore è quello usato e quali sono i parametri. Insomma, sono poco "parlanti".

    L'alternativa sarebbe avere una classe che sia un semplice java bean con metodi setter/getter ma questo impedirebbe l'immutabilità e permetterebbe (volutamente o non) di avere uno stato "inconsistente" dell'oggetto.

    L'alternativa più interessante è l'uso di una variante del pattern "Builder". La classe quindi non ha costruttori o metodi "factory" direttamente accessibili ma invece è un oggetto Builder che costruisce la istanza. E l'oggetto Builder ha metodi per settare le varie informazioni e poi un unico build() per costruire la istanza (dove si possono anche testare degli invariant, eventualmente).
    La classe Builder tipicamente la si fa come classe "membro" statica della classe dei tuoi oggetti.

    Da usare poi ad esempio come es.:

    codice:
    PunteggioGioco.Builder pgBuilder = new PunteggioGioco.Builder();
    pgBuilder.nick("pippo");
    pgBuilder.eta(20);
    ...
    PunteggioGioco pg = pgBuilder.build();
    Generalmente si fa che quei metodi ritornano lo stesso oggetto Builder, per poter usare il method chaining. Quindi per un uso arbitrario fatto direttamente dal programmatore si potrebbe anche fare:

    codice:
    PunteggioGioco pg = new PunteggioGioco.Builder().nick("pippo").eta(20).build();
    Ma ovviamente nel tuo caso essendo il tutto "pilotato" dai dati vorrà dire che si deve usare la prima forma (invocazioni separate) e invocare il tal metodo solo se trovi il dato nella riga.

    Ti è sufficiente quanto ho detto? (credo/spero di sì, anche perché ho detto parecchio!)
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Si diciamo che è sufficiente per capire che devo studiare qualcosa.
    Leggo quanto mi serve su Builder e dopo vedo, scriverò io domani se sono riuscito a scrivere qualcosa.
    Grazie mille.

  4. #4
    Io ho creato una classe:

    codice:
    public class Punteggi
    	{
    	  public String nick="";			
    	  public int p=""; 			//punteggio
    	  public int a=""; 			//età
    	  public String i="";	                        //data iscrizione
    	  public int n=""; 			//numero partite giocate
    	  public int u="";	 			//ultimo punteggio ottenuto
    	  public String dp="";			            //data punteggio
    	  public boolean bonus=false;                       //se presente indica che c'è bonus
    	
    	
    		public Punteggi(String nick, int p, int a, String i int n, int u, String dp, boolean bonus)
    		{
    			this.nick=nick;
    			this.p=p;
    			this.i=i;
    			this.a=a;
    			this.n=n;
    			this.u=u;
    			this.dp=dp;
    			this.bonus=bonus;
    		}
    		
    		public String getNick()
    		{
    			return nick;
    		}
    		public int getP()
    		{
    			return p;
    		}
    		
    		public int getA()
    		{
    			return a;
    		}
    		
    		
    		public String getI()
    		{
    			return i;
    	
    		public int getN()
    		{
    			return n;
    		}
    		
    		public int getU()
    		{
    			return u;
    		}
    		
    		public String getDP()
    		{
    			return dp;
    		
    		public boolean getBonus()
    		{
    			return bonus;
    		}
    		
    		public String toString()
    		{
    			return "("+getNick()+", "+getP()+"), nome: "+getN()+", "+getA()+" anni, punteggio ottenuto il "+getP()+", "+getN()+" partite giocate, iscritto dal "+getI()+", ultimo punteggio ottenuto :"+getU()+","+getBonus();
    }

    che dovrebbe essere quella generale, e ora dovrei costruire gli oggetti in un' altra classe?
    Leggendo dal file le varie righe, per esempio con la classe Scanner, passando come parametro una stringa, verifico se quello che leggo è uguale a "-nick", e in caso affermativo
    dovrei costruire il mio oggetto con parametro nick??
    Ho letto il pattern ma l'idea che mi sono fatto non è chiarissima, su come fare interagire le varie cose più che altro.
    Non ricordo con Scanner se nel caso in cui un token è lo spazio salta automaticamente all'altro o devo fare due letture.

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Darèios89
    codice:
    	  public int p=""; 			//punteggio
    	  public int a=""; 			//età
    Robe di questo tipo, assegnare un String "" a un int ovviamente non stanno né in cielo né in terra .....
    E mettere i campi con accesso "public" non è nemmeno una buona cosa.

    Originariamente inviato da Darèios89
    public Punteggi(String nick, int p, int a, String i int n, int u, String dp, boolean bonus)
    Se è pubblico ..... chiunque lo può usare. Se deve essere solo l'oggetto Builder che deve poter istanziare questi oggetti ovviamente non va molto bene.

    E la classe si dovrebbe chiamare Punteggio perché "modella" 1 punteggio (e altri dati) associato ad un nick .... non più punteggi.

    Originariamente inviato da Darèios89
    this.p=p;
    this.i=i;
    this.a=a;
    this.n=n;
    this.u=u;
    this.dp=dp;
    Una delle prime regole della programmazione in generale: dare dei nomi sensati agli elementi (variabili, ecc....) del programma. 'p' 'i' 'a' 'n' ecc..... ti paiono nomi molto sensati e "parlanti"??? A me pare proprio di no ....

    Originariamente inviato da Darèios89
    e ora dovrei costruire gli oggetti in un' altra classe?
    Ma intendi seguire quanto detto nel testo iniziale e cioè usare un oggetto "Builder"??

    Naturalmente io avevo supposto (e lo suppongo tuttora) che si tratta proprio di quello di cui parla il libro "Effective Java" di Joshua Bloch. Ovvero una variante del pattern Builder realizzata con una nested class interna alla classe dei tuoi oggetti.

    Originariamente inviato da Darèios89
    Leggendo dal file le varie righe, per esempio con la classe Scanner, passando come parametro una stringa, verifico se quello che leggo è uguale a "-nick", e in caso affermativo
    dovrei costruire il mio oggetto con parametro nick??
    In una riga hai tanti "token" separati da spazi, compreso l'ultimo token ";".
    E quindi Scanner va appunto benissimo per estrarre i token uno dopo l'altro (lasciando a Scanner l'incombenza di spezzare la sequenza usando i whitespace che per default sono il "delimitatore").

    Solo che devi prestare un po' di attenzione, perché hai tutti i token uno dietro l'altro: ...... "-u" poi "5643" poi ";" poi "-nick" poi "AGIULIANI" .....

    Quindi quando trovi ";" devi trattarlo come "fine del record" e quindi devi prepararti per la creazione di un nuovo oggetto.

    Originariamente inviato da Darèios89
    Ho letto il pattern ma l'idea che mi sono fatto non è chiarissima, su come fare interagire le varie cose più che altro.
    La variante del pattern Builder l'ho descritta prima e ho anche fatto un esempio di come dovrebbe/potrebbe essere usato.

    Originariamente inviato da Darèios89
    Non ricordo con Scanner se nel caso in cui un token è lo spazio salta automaticamente all'altro o devo fare due letture.
    Il delimitatore di default è "uno o più whitespace" (whitespace=spazio,tab,carriage return,ecc...). Testando in ciclo hasNext() ed estraendo i token con next() li ottieni tutti uno dopo l'altro.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.