|
|
|
![]() |
|
Strumenti |
![]() |
#21 | |
Senior Member
Iscritto dal: Jul 2004
Messaggi: 1578
|
Quote:
|
|
![]() |
![]() |
![]() |
#22 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
Ad esempio... Una classe che genera numeri pseudocasuali (il numero generato non è contenuto all'interno della classe)... Ultima modifica di cionci : 08-11-2005 alle 11:03. |
|
![]() |
![]() |
![]() |
#23 |
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
credo che forse sia perchè sono abituato ad una fase di testing da consol, ad una fase di testing sui dati che mi servono, e forse perchè non ho mai avuto un progetto davvero grosso per le mani.
Comunque, è vero che non le diminuiscono, ma il loro aumento è quais pari a zero, e per una eventuale fase di debug da console(io faccio quella, e magari sbaglio, nn lo metto in dubbio), mi trovo metodi di accesso e di controllo sui dati molto rapidi.
__________________
My gaming placement |
![]() |
![]() |
![]() |
#24 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
![]() Io faccio un discorso un po' piu' generale. L'unico caso in cui posso capire il non proteggere un campo e' l'uso di value type che sono strettamente dati, ad esempio un descrittore: (C++) Codice:
struct CreationFlags { bool Flag1; bool Flag2; int NumberOfSomething; }; ... CreationFlags flags; flags.Flag1 = true; ... something.Create(flags); In tutti gli altri casi i campi pubblici vanno sempre protetti.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#25 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Di nuovo l'esempio dell'andare da casa al lavoro, compreresti l'elicottero perche' magari un giorno ti potrebbe servire per andare in Sardegna? Oppure una bicicletta o una macchina che costano meno?
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#26 | |
Senior Member
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
|
Quote:
![]() ![]() ![]() ![]() ![]() ![]()
__________________
My gaming placement |
|
![]() |
![]() |
![]() |
#27 | |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Quote:
Non lasciare campi pubblici e permettere l'accesso ai campi privati con metodi setter e getter permette una maggiore manutenibilità del codice... Pensate se la struttura interna di una classe dovesse cambiare radiacalmente dopo la sua prima implemntazione... Se la variabile pubblica non avesse più senso senza doverla elaborare ci troveremmo di fronte ad un grosso problema per chi accede a quella variabile (cambiare il nome alla variabile e modificare tutte le occorrenze e l'uso nel codice)... Ad esempio una classe Angolo... Si espone una variabili pubblica gradi... Ad un certo punto però i calcoli li vogliamo fare in radianti... Dobbiamo quindi convertire la variabile gradi in radianti per ogni metodo della classe che la usa... Se si usano i metodi setGradi e getGradi, possiamo implementare una conversione all'interno di questi metodi, modificando la rappresentazione interna in radianti... Quindi io sono per nessun membro pubblico... Ultima modifica di cionci : 08-11-2005 alle 11:20. |
|
![]() |
![]() |
![]() |
#28 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
![]() In Diamonds usiamo un check che non permette i commit se un campo di una qualunque classe e' pubblico. Questa pratica si paga in termini di tempo necessario a scrivere i metodi di accesso, ma garantisce un numero minore di difetti. Si paga per avere qualcosa in cambio.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#29 |
Senior Member
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
|
Per la necessità di implementare tutti i setter e i getter...anche qui, mi limito ad implementare quelli che servono all'esterno... Senza contare che non tutti i membri privati hanno un senso per l'esterno...della serie...la variabile è mia (della classe) e me la gestisco come mi pare...
Inoltre una volta implementati tutti i setter ed i getter, ma voglio rivoluzionare la rappresentazione interna della classe devo modfiicarli per renderli compatibili con la rappresentazione attuale (mantendo gli stessi nomi dei metodi) ed aggiungere i setter ed i getter per la nuova struttura interna... Quindi non solo mi sembra controproducente mettere un set ed un get per ogni variabile privata, ma addirittura assurdo, soprattutto in uno sviluppo di team in cui l'interfaccia della classe deve rimanere il più possibile costante... Ultima modifica di cionci : 08-11-2005 alle 11:27. |
![]() |
![]() |
![]() |
#30 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
![]() http://www.amazon.com/exec/obidos/tg...84649?v=glance (Io sono d'accordo con te) La logica dietro quello che dice Meyers pero' e' molto sensata, perche' il suo scopo e' disaccoppiare sempre e comunque interfaccia (anche interna) dall'implementazione. Inoltre, ogni entita' deve avere accesso al minimo di informazioni che gli serve per lavorare. E quindi tutti i campi anche privati vanno dietro a get/set, perche' disaccoppi il cliente dalla loro rappresentazione e gli fornisci il minimo delle informazioni che gli servono. Meyers dice anche che i metodi dell'interfaccia pubblica di una classe in C++ devono essere funzioni libere non friend, sempre per il principio che non devono avere accesso alla rappresentazione interna della classe, e devono essere disaccoppiati dall'implementazione. Inoltre, dice che i metodi virtuali devono essere sempre privati e delegati da metodi pubblici non virtuali, perche' un metodo virtuale pubblico vuole risolvere due forze contrastanti: da una parte definire l'interfaccia verso l'esterno, dall'altra definire i punti di modifica virtuale per le classi derivate. Secondo il principio che un'entita deve avere una e una sola responsabilita', crei per uno o piu' metodi virtuali, dei metodi non virtuali pubblici (magari esterni) che disaccoppiano l'interfaccia pubblica della classe dai punti di aggancio per le classi derivate. *pant* *pant* Tutto questo sproloquio per dire che? Per dire che se applici alla lettera tutte queste regolette ti ritrovi con codice un po' troppo "bloated" e ampolloso, ma e' buona cosa conoscerle a mio avviso, per poterle applicare quando ti risolvono effettivamente un problema. E allora io uso metodi get/set per campi privati quando ho bisogno di disaccoppiare il codice interno dall'implementazione, uso metodi pubblici di accesso a metodi virtuali quando voglio disaccoppiare l'interfaccia della classe dai punti di aggancio. Etc etc... Tutto nell'ottica di spendere il meno possibile, perche' sono pigro ![]()
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#31 | |
Senior Member
Iscritto dal: Apr 2005
Città: <-|-|-*|*-|-|->
Messaggi: 347
|
Quote:
![]() la mia domanda è questa: ok che va bene inizializzare le variabili nel costruttore, ma il fatto è che sto lavorando a un progetto in cui per inizalizzare le mie variabili all'interno del costruttore devo chiamare dei metodi in un'ordine preciso, altrimenti la classe viene creata in modo sbagliato ... spero di essermi spiegato stavolta. Quindi il punto è questo: è corretto o no? un futuro se un mio collega vuole lavorare sulle classi che sto scrivendo e non capisce che nel costruttore prima deve essere chiamato il metodo1 e poi il metodo2 affinchè alcuni campi della classe non rimangano non inizializzati manderà in palla il programma e non capirà perchè non funziona! Quindi a mia "discolpa" è sufficente che io commenti bene i diversi metodi (compreso il costruttore ovviamente) della mia classe in modo da spiegarne l'utilizzo? Per utilizzo intendo ad esempio l'ordine in cui devono essere chiamati all'interno del costruttore per creare un oggetto che abbia senso per il tipo di problema che voglio risolvere. Spero di essere stato chiaro. Non intendevo sollevare un polverone sull'utilizzo dei metodi setter e getter... ![]() Ultima modifica di shang84 : 08-11-2005 alle 13:47. |
|
![]() |
![]() |
![]() |
#32 |
Messaggi: n/a
|
classico scontro tra mondo accademico e mondo industriale
![]() l'opportunita di definire dei get e set e altri metodi di utilità viene dettato sopratutto dal/dai pattern di progettazione (ingegneria del software) che hai deciso di usare e in parte anche a quello che serve il codice che stai scrivendo. per il discorso della leggibilità del codice... beh non lo so, nessuno può accusare che il mondo accademico produce codice ampolloso e poco leggibile quella è un arte di una certa fetta di mondo industriale (per quanto riguarda la leggibilità e documentazione) vecchio stampo (10 anni) ma anche videoludico... a vedere certi sorgenti come quake1, quake2, hl2 sono così "essenziali" che senza una precisa (ma assente) documentazione non si capisce assolutamente nulla. |
![]() |
![]() |
#33 | |
Messaggi: n/a
|
Quote:
|
|
![]() |
![]() |
#34 |
Senior Member
Iscritto dal: Apr 2005
Città: <-|-|-*|*-|-|->
Messaggi: 347
|
Quindi da quel che mi dici se esiste un'ordine in cui devono essere chiamati i metodi "pseudo-setter"* all'interno del costruttore non è un errore. L'importante è che lo scrivo nella documentazione in modo da facilitare chi poi lavorerà sulla mia classe.
*"pseudo-setter" - metodi che inizializzano più di una variabile e che mi non si chiamano setNomeVariabile ma con un altro nome. La funzione però è simile. Perdonatemi fantasioso dei termini! Ad esempio nel progetto a cui sto lavorando non ho messo alcun setter, in quanto tutti i metodi (pseudo-setter) che inizializzano variabili li chiamo dal costruttore una volta sola. In altri progetti invece ho scritto il metodo setter e getter per ciascun attributo.. ma è dipeso dal tipo di problema che dovevo risolvere. In questo progetto alcune classi sono "usa e getta", nel senso che una volta che ho creato l'oggetto, ne stampo il contenuto su file e poi lo dealloco... senza aver necessità di accedere ai campi tramite metodi getter. Uso solo un metodo "print" che stampa in output tutti gli attributi e poi l'output lo ridireziono su file. Anche qui, alcune norme di ingegneria del software direbbero che è scorretto mettere una stampa in output direttamente nella classe... E' anche in questo caso una cosa solamente terica? Norme in questione Le norme in questione infatti dicono che è bene che ci sia un: PRESENTATION LAYER [interagisce con l'utente e invia i dati in input al business layaer] BUSINESS LAYER [.. il quale li rielabora e accede alle classi tramite i metodi setter e getter] DATA LAYER [in cui sn memorizzati gli oggetti dato] |
![]() |
![]() |
![]() |
#35 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
Non devi neppure commentarlo. Discorso leggermente diverso se il tuo collega deve "mantenere", quindi modificare la classe che hai scritto tu, quindi deve sapere che il costruttore deve chiamare due metodi in un certo ordine per la corretta creazione della classe. Come fare? Una soluzione potrebbe essere commentare il codice, qualcosa del tipo: [Java] Codice:
MyClass() { // ... // method1() dev'essere chiamato prima di chiamare method2() method1(); method2(); // ... } Vediamo questa versione: [Java] Codice:
MyClass() { // ... firstStepOfInitialisation(); secondStepOfInitialisation(); // ... } Che succede se il mio collega e' magari un po' stanco, ha fretta e modifica questo codice in questa maniera? [Java] Codice:
MyClass() { // ... firstStepOfInitialisation(); // ... } Il problema si risolve testato automaticamente che il primo metodo e' chiamato prima del secondo. Ma questo e' un altro argomento.
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#36 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
![]() "I commenti sono un deodorante per il codice. Meglio eliminare la puzza."
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#37 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
#38 | ||
Senior Member
Iscritto dal: Apr 2005
Città: <-|-|-*|*-|-|->
Messaggi: 347
|
Quote:
Quote:
L'inizializzazione corretta dell'oggetto dipende dal file passato in input al programma, se non è corretto il programma non inizializza l'oggetto (Eccezione) se è corretto lo inizializza e poi ne stampa il contenuto.. infine dealloca l'oggetto creato. |
||
![]() |
![]() |
![]() |
#39 | |
Senior Member
Iscritto dal: Apr 2005
Città: <-|-|-*|*-|-|->
Messaggi: 347
|
Quote:
Per il testaggio sto utilizzado dei flag booleani, il concetto è questo: se tutti i flag sono true allora l'oggetto è inizializzato corretamente. Ad es: il metodo1 ha bisogno che il flag0 sia inizializzato a true per fare il suo lavoro, e cosi via. Se alla fine esiste almeno un flag false allora l'oggetto è stato creato scorrettamente. |
|
![]() |
![]() |
![]() |
#40 | |
Senior Member
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
|
Quote:
__________________
"We in the game industry are lucky enough to be able to create our visions" @ NVIDIA |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 05:22.