Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Realizzato da Lenovo e installato presso il Cineca di Casalecchio di Reno, Pitagora offre circa 44 PFlop/s di potenza di calcolo ed è dedicato alla simulazione della fisica del plasma e allo studio dei materiali avanzati per la fusione, integrandosi nell’ecosistema del Tecnopolo di Bologna come infrastruttura strategica finanziata da EUROfusion e gestita in collaborazione con ENEA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Rullo di lavaggio dei pavimenti abbinato a un potente motore da 28.000 Pa e a bracci esterni che si estendono: queste, e molte altre, le caratteristiche tecniche di Z60 Ultra Roller Complete, l'ultimo robot di Mova che pulisce secondo le nostre preferenze oppure lasciando far tutto alla ricca logica di intelligenza artificiale integrata
Renault Twingo E-Tech Electric: che prezzo!
Renault Twingo E-Tech Electric: che prezzo!
Renault annuncia la nuova vettura compatta del segmento A, che strizza l'occhio alla tradizione del modello abbinandovi una motorizzazione completamente elettrica e caratteristiche ideali per i tragitti urbani. Renault Twingo E-Tech Electric punta su abitabilità, per una lunghezza di meno di 3,8 metri, abbinata a un prezzo di lancio senza incentivi di 20.000€
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 16-04-2005, 19:41   #1
prazision
Senior Member
 
L'Avatar di prazision
 
Iscritto dal: Dec 2003
Messaggi: 458
[JAVA]ereditarietà

finora ho utlizzato java per creare delle classi abbastanza semplici che ho utilizzato nelle mie pagine jsp:
una classe che mi genera una password, delle classi(e delle servlet) che mi generano dei file pdf, ecc.

approfondendo java ho studiato(per ora in maniera abbastanza generica) l'ereditarietà, il polimorfismo ecc.

ecco mi chiedo: in casi come il mio, dove al massimo si tratta di progettini con 4 o 5 classi, conviene(insomma si usa) creare comunque delle classi astratte ed utilizzare l'ereditarietà??
nel senso che a me , in progettini così semplici, non mi sembra che se ne possa trarre un gran beneficio (probabilmente l'inesperienza e l'ignoranza non mi fanno vedere le cose come stanno)

aspetto consigli

grazie
prazision è offline   Rispondi citando il messaggio o parte di esso
Old 16-04-2005, 20:23   #2
Mixmar
Senior Member
 
L'Avatar di Mixmar
 
Iscritto dal: Feb 2002
Città: Trento
Messaggi: 962
Da un certo punto di vista hai ragione tu, l'ereditarietà è uno strumento potente, ma va usato con criterio, e in progetti "semplici" (non ci sono progetti semplici! ) potrebbe generare più problemi di quelli che sarebbe eventualmente in grado di risolvere.

Diverso è il discorso, se tu dovessi decidere di riutilizzare il codice che hai creato per altri progetti: trattandosi, come dici, di componenti estremamente semplici ma fondamentali, è altamente probabile che in futuro tu possa utilizzarli nuovamente. Qualora ciò dovesse accadere, averli strutturati fin da principio sfruttando rigorosamente l'ereditarietà potrebbe giovarti non poco...
__________________
"Et Eärallo Endorenna utúlien. Sinome maruvan ar Hildinyar tenn' Ambar-metta!" -- Aragorn Elessar, Heir of Isildur
Mixmar -- OpenSuSE 11.1 on AMD 64 3000+ on DFI LanParty nF4-D | GeForce 6600 GT + Thermaltake Schooner on Samsung 710N
Storage -- ( 2 x Hitachi Deskstar 80 Gb + 1 x Hitachi 250 Gb ) = 1 RAID 5 + 1 Storage space LaCie Ethernet Disk Mini 250 Gb | HP - DV2150 EL MILAN CLAN
Mixmar è offline   Rispondi citando il messaggio o parte di esso
Old 16-04-2005, 20:51   #3
prazision
Senior Member
 
L'Avatar di prazision
 
Iscritto dal: Dec 2003
Messaggi: 458
penso d'aver capito cosa intendi.
magari dei metodi sono generici e riutilizzabili in + progetti(faccio un esempio eh) e conviene pertanto scriverli in classi padri.

è ovvio che ora, limitandomi ad utilizzare le classi in un singolo progetto, non riesco a vedere l'utilità di tale approccio

cmq grazie
prazision è offline   Rispondi citando il messaggio o parte di esso
Old 17-04-2005, 10:36   #4
Mixmar
Senior Member
 
L'Avatar di Mixmar
 
Iscritto dal: Feb 2002
Città: Trento
Messaggi: 962
Certo, oppure potresti voler usare le interfacce anzichè le classi per poter un giorno estendere il tuo progetto con nuove funzionalità non previste, il tutto senza dover riscrivere (idealmente ) le classi vecchie per farle funzionare con quelle nuove... con tanti vantaggi: possibilità di fare test, passaggio graduale tra un progetto e un altro, eccetera.
__________________
"Et Eärallo Endorenna utúlien. Sinome maruvan ar Hildinyar tenn' Ambar-metta!" -- Aragorn Elessar, Heir of Isildur
Mixmar -- OpenSuSE 11.1 on AMD 64 3000+ on DFI LanParty nF4-D | GeForce 6600 GT + Thermaltake Schooner on Samsung 710N
Storage -- ( 2 x Hitachi Deskstar 80 Gb + 1 x Hitachi 250 Gb ) = 1 RAID 5 + 1 Storage space LaCie Ethernet Disk Mini 250 Gb | HP - DV2150 EL MILAN CLAN
Mixmar è offline   Rispondi citando il messaggio o parte di esso
Old 17-04-2005, 12:09   #5
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da prazision
finora ho utlizzato java per creare delle classi abbastanza semplici che ho utilizzato nelle mie pagine jsp:
una classe che mi genera una password, delle classi(e delle servlet) che mi generano dei file pdf, ecc.

approfondendo java ho studiato(per ora in maniera abbastanza generica) l'ereditarietà, il polimorfismo ecc.

ecco mi chiedo: in casi come il mio, dove al massimo si tratta di progettini con 4 o 5 classi, conviene(insomma si usa) creare comunque delle classi astratte ed utilizzare l'ereditarietà??
nel senso che a me , in progettini così semplici, non mi sembra che se ne possa trarre un gran beneficio (probabilmente l'inesperienza e l'ignoranza non mi fanno vedere le cose come stanno)

aspetto consigli

grazie
Come ti hanno gia' risposto giustamente non esistono progetti semplici e l'ereditarieta' e' uno strumento potente e come tale deve essere usato solo quando e' necessario.

Il problema ora e' capire quando e' necessario.

La regola e' che si eredita' una classe da un'altra nel momento in cui si deve modellare una relazione "is a" ("E' un" in italiano). Questa e' la regola generale. Una regoletta pratica e' usare l'ereditarieta' quando vuoi che un oggetto sia usabile in tutte le condizioni al posto dell'oggetto dal quale deriva; si chiama principio di sostituzione. Non si usa l'ereditarieta' per estendere le funzionalita' di una classe. Esistono tecniche piu' efficaci per risolvere questo problema.

Lo so che probabilmente ti hanno detto il contrario all'universita' o a scuola, ti avranno parlato di riutilizzabilita' del codice, di codice generico da estendere, di come l'ereditarieta' sia lo strumento per raggiungere la chimera della totale riutilizzabilita'. Dimenticatene

Ti faccio qualche esempio per chiarire il discorso. Immagina una classe astratta (interfaccia in Java) di nome IRunnable, che definisce un metodo astratto run(). Ora immagina di avere una classe Command che esegue un qualche comando, magari in risposta ad un input dell'utente. Ha molto senso che la classe Command erediti dalla classe astratta (interfaccia) IRunnable ed implementi il metodo run() per eseguire un'operazione in risposta all'input dell'utente. Il codice di "dispatch" dei comandi, vedra' oggetti del tipo IRunnable e si limitera' ad eseguire il metodo run(): questa situazione e' un classico esempio di applicazione del principio di sostituzione perche' un oggetto di classe Command puo' essere in tutti gli aspetti usato "come se fosse" di tipo IRunnable. In questa situazione l'Ereditarieta' ha molto senso.

Ora immagina di voler implementare una classe Command che al momento di eseguire il comando stampi in un qualche file di log una stringa che rappresenta l'operazione eseguita. Come implementeresti questa classe?

1) Crei una nuova classe LoggedCommand che eredita da Command e prima di eseguire il metodo run() del comando scrive il messaggio di log:

Codice:
class LoggedCommand extends Command
{
   // ...
   void run()
   {
      logger.print("logging command");
      super.run();
   }
}
2) Nel metodo run() della classe Command aggiungi un if che scrive sul file di log in caso il logging sia attivato:

Codice:
void run()
{
   if (logger != null)
     logger.print("logging command");
   
   // codice di esecuzione del comando
}
3) Crei un "adapter" che accetta un oggetto di tipo IRunnable e nel suo metodo run() stampa il messaggio di log e poi esegue il metodo run dell'oggetto che gli e' stato passato (delega):

Codice:
class LoggingRunnable extends IRunnable
{
   IRunnable target;

   LoggingRunnable(IRunnable target)
   {
      this.target = target;
   }

   void run()
   {
      logger.print("add logging here");
      target.run();
   }
}
Quale delle tre soluzioni sceglieresti? Prova a rispondere sulla base di quello che ho scritto prima, la risposta secondo me e' molto interessante e non e' affatto banale e ne puo' scaturire una discussione interessante.
Ti do' un suggerimento: quando hai da fare una scelta mentre programmi scegli sempre la soluzione che sia "il piu' semplice possibile, ma non piu' semplice" ("As simple as possible, but not simpler").

PS. Scusatemi se ho fatto casino con la sintassi fra Java e C#, ma non ho compilato il codice.
fek è offline   Rispondi citando il messaggio o parte di esso
Old 17-04-2005, 14:37   #6
prazision
Senior Member
 
L'Avatar di prazision
 
Iscritto dal: Dec 2003
Messaggi: 458
Quote:
Originariamente inviato da fek
ne puo' scaturire una discussione interessante.
si, ma solo se partecipa anche quacluno unpo'+ ferrato di me

dunque:
intanto cosa intendi per 'codice di "dispatch" dei comandi'?
poi non ho capito perchè nell'esempio date fatto "l'Ereditarieta' ha molto senso";

per quanto riguarda l'indovinello ( ) escluderei la soluzione 2 in modo da conservare la mia classe Command.
la terza soluzione mi sembra forse la più elastica( e quindi la preferisco alla prima) perchè consente di passare a LoggingRunnable altri eventuali oggetti (nel senso di altre classi che estendono IRunnable )

tieni conto che sono andato molto a intuito, è la prima volta che ragiono su cose simili

cmq grazie
prazision è offline   Rispondi citando il messaggio o parte di esso
Old 17-04-2005, 14:59   #7
prazision
Senior Member
 
L'Avatar di prazision
 
Iscritto dal: Dec 2003
Messaggi: 458
pensandoci bene posso raffigurarmi il perchè nel tuo esempio(magari estendendolo unpo') l'ereditarietà ha una certa importanza
prazision è offline   Rispondi citando il messaggio o parte di esso
Old 18-04-2005, 15:21   #8
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da prazision
intanto cosa intendi per 'codice di "dispatch" dei comandi'?
poi non ho capito perchè nell'esempio date fatto "l'Ereditarieta' ha molto senso";
Hai ragione, scusa. Per "dispatch" intendo il codice che si occupa di smistare l'esecuzione dei comandi.

Nell'esempio che ho fatto (IRunnable e Command), l'ereditarieta' ha molto senso perche' un oggetto di tipo Command puo' essere usato ovunque un oggetto di tipo IRunnable puo' essere usato. In altre parole puoi sempre ignorare il fatto che un oggetto sia di tipo Command e usarlo esattamente come se fosse di tipo IRunnable.

Quote:
per quanto riguarda l'indovinello ( ) escluderei la soluzione 2 in modo da conservare la mia classe Command.
la terza soluzione mi sembra forse la più elastica( e quindi la preferisco alla prima) perchè consente di passare a LoggingRunnable altri eventuali oggetti (nel senso di altre classi che estendono IRunnable )

tieni conto che sono andato molto a intuito, è la prima volta che ragiono su cose simili
Va benissimo, non ti preoccupare.
La risposta esatta e'... dipende

Quale delle tre soluzioni scegli dipende dal problema che devi risolvere e da cio' che stai scrivendo e dalla sua complessita'.
Nel 99%, appena ho il problema di dover loggare un comando, io sceglierei la soluzione numero 2 perche' e' la piu' semplice e veloce da implementare. E come ti dicevo prima, devi sempre scegliere la soluzione piu' semplice che risolve il tuo problema salvo complicarla e renderla piu' flessibile solo quando hai bisogno di quella flessibilita'. Ad esempio, la soluzione numero 3, come hai detto giustamente tu, e' piu' flessibile delle altre due, ma questa flessibilita' si paga con una classe in piu' da scrivere (l'Adattatore) e con il suo codice in piu' da scrivere, debuggare, testare e mantenere.
Se ti serve solo loggare la classe di tipo Command e nient'altro, scrivere un Adattatore e' un peso che ti porti dietro nel design inutile perche' non stai sfruttando la flessibilita' che ti garantisce, ma, presumibilmente, aspetti di poterla sfruttare in seguito caso mai ce ne fosse bisogno. Ma nel frattempo paghi il costo e quel momento in cui ti serve la flessibilita' potrebbe non arrivare mai (e di solito non arriva). Pagheresti in anticipo dei soldi per un oggetto che magari potrebbero darti in seguito (o magari no)? Ovviamente no, ti terrai quei soldi e li spenderai quando il bene sara' disponibile. Quando programmi il principio e' uguale: non pagare mai il costo associato con un design piu' flessibile se non hai un bisogno immediato e tangibile ed un problema da risolvere.

Ritorno all'esempio: nel momento in cui ti servira' loggare comandi di tipo diverso, con la soluzione 2) dovrai aggiungere quell'if in tutte le classi loggabili, potenzialmente molte, una soluzione chiaramente non ideale. Quando sarai in quella situazione ed avrai quella necessita' (se l'avrai), potrai riorganizzare il codice (refactoring) e spostare la logica di logging in una classe Adattatore. Applicherai quello che in gergo si definisce "Muovere l'Embellishment (Abbellimento) in un Adapater (Adattatore)". Fino a quel momento l'if (soluzione 2) risolve bene il problema ed e' la soluzione piu' semplice. La semplicita' e' il primo valore che devi seguire quando programmi.

Perche' la soluzione 3 e' preferibile alla 1? Qui entra in gioco l'esperienza. Dall'esperienza io so che creare una classe LoggingCommand ereditata da Command puo' portare a situazioni in cui e' necessario avere un tipo di comando particolare che puo' essere loggato o meno, con conseguente esplosione nel numero delle classi. Da qui all'avere classi tutte del tipo NotLoggingSpecificCommand e LoggingSpecificCommand il passo e' brevissimo e questa situazione diventa velocemente molto complicata da gestire. L'esperienza e la ricerca di semplicita' mi dicono che se avessi bisogno di piu' flessibilita' la soluzione 3 e' preferibile alla 1.

In sintesi: l'ereditarieta' e' uno strumento potete ma che va usato con molta attenzione, perche' puo' portare notevoli complicazioni ed un design, in definitva, peggiore. Eredita solo quando ti e' strettamente necessario, all'inizio eredita' solo nel caso in cui ti ho detto qui, quando puoi applicare il principio di sostituibilita'.
fek è offline   Rispondi citando il messaggio o parte di esso
Old 18-04-2005, 16:16   #9
prazision
Senior Member
 
L'Avatar di prazision
 
Iscritto dal: Dec 2003
Messaggi: 458
appena posso ci do un occhio
grazie
prazision è offline   Rispondi citando il messaggio o parte di esso
Old 18-04-2005, 21:27   #10
prazision
Senior Member
 
L'Avatar di prazision
 
Iscritto dal: Dec 2003
Messaggi: 458
Quote:
Originariamente inviato da fek
Hai ragione, scusa. Per "dispatch" intendo il codice che si occupa di smistare l'esecuzione dei comandi.
diciamo che se fai un progettino che visualizzi dalla console il "dispatch" è il codice contenuto nel metodo main, no?


Quote:
Originariamente inviato da fek
Nell'esempio che ho fatto (IRunnable e Command), l'ereditarieta' ha molto senso perche' un oggetto di tipo Command puo' essere usato ovunque un oggetto di tipo IRunnable puo' essere usato. In altre parole puoi sempre ignorare il fatto che un oggetto sia di tipo Command e usarlo esattamente come se fosse di tipo IRunnable.
si ma detto così a me non sembra tanto utile (addirittura ti vado contro ); un esempio che mi sembra più appropriato è:
ho una classe Programma.java che chiama un metodo
Distruggi(IRunnable iRun)
poi ho varie classi che estendono IRunnable : Command,Command2,ecc.
ecco a seconda di quale classe(sto pensando ad esempio ad un parametro che viene passato dall'utente di volta in volta, un parametro che indica appunto la classe) passi a Distruggi() questo metodo si comporta in maniera differente.
così mi spiego il perchè ho usato l'ereditarieta'
(so che è un esempio unpo' del c****) ma spero tu abbia capito


Quote:
Originariamente inviato da fek
Va benissimo, non ti preoccupare.
La risposta esatta e'... dipende

Quale delle tre soluzioni scegli dipende dal problema che devi risolvere e da cio' che stai scrivendo e dalla sua complessita'.
Nel 99%, appena ho il problema di dover loggare un comando, io sceglierei la soluzione numero 2 perche' e' la piu' semplice e veloce da implementare. E come ti dicevo prima, devi sempre scegliere la soluzione piu' semplice che risolve il tuo problema salvo complicarla e renderla piu' flessibile solo quando hai bisogno di quella flessibilita'. Ad esempio, la soluzione numero 3, come hai detto giustamente tu, e' piu' flessibile delle altre due, ma questa flessibilita' si paga con una classe in piu' da scrivere (l'Adattatore) e con il suo codice in piu' da scrivere, debuggare, testare e mantenere.
Se ti serve solo loggare la classe di tipo Command e nient'altro, scrivere un Adattatore e' un peso che ti porti dietro nel design inutile perche' non stai sfruttando la flessibilita' che ti garantisce, ma, presumibilmente, aspetti di poterla sfruttare in seguito caso mai ce ne fosse bisogno. Ma nel frattempo paghi il costo e quel momento in cui ti serve la flessibilita' potrebbe non arrivare mai (e di solito non arriva). Pagheresti in anticipo dei soldi per un oggetto che magari potrebbero darti in seguito (o magari no)? Ovviamente no, ti terrai quei soldi e li spenderai quando il bene sara' disponibile. Quando programmi il principio e' uguale: non pagare mai il costo associato con un design piu' flessibile se non hai un bisogno immediato e tangibile ed un problema da risolvere.

Ritorno all'esempio: nel momento in cui ti servira' loggare comandi di tipo diverso, con la soluzione 2) dovrai aggiungere quell'if in tutte le classi loggabili, potenzialmente molte, una soluzione chiaramente non ideale. Quando sarai in quella situazione ed avrai quella necessita' (se l'avrai), potrai riorganizzare il codice (refactoring) e spostare la logica di logging in una classe Adattatore. Applicherai quello che in gergo si definisce "Muovere l'Embellishment (Abbellimento) in un Adapater (Adattatore)". Fino a quel momento l'if (soluzione 2) risolve bene il problema ed e' la soluzione piu' semplice. La semplicita' e' il primo valore che devi seguire quando programmi.
fin quì mi sembra tutto limpido


Quote:
Originariamente inviato da fek
Perche' la soluzione 3 e' preferibile alla 1? Qui entra in gioco l'esperienza. Dall'esperienza io so che creare una classe LoggingCommand ereditata da Command puo' portare a situazioni in cui e' necessario avere un tipo di comando particolare che puo' essere loggato o meno, con conseguente esplosione nel numero delle classi. Da qui all'avere classi tutte del tipo NotLoggingSpecificCommand e LoggingSpecificCommand il passo e' brevissimo e questa situazione diventa velocemente molto complicata da gestire.
mi pare di capire che tu quì dici:
ci sono varie classi : Command,Command1 ecc.; alcune vanno "loggate", altre no.
se uso il metodo 1 dovro' costruirmi tanti LoggedCommand/NonLoggedCommand quanti sono le classi Command mentre se uso il metodo 3 mene basteranno 2 di classi.
è così?

grazie di tutto, ho dato un occhio al tuo link e ti dico che durante la messa del mio matrimonio si ascolteranno non solo Fugazi ma anche S.Youth, Wire, Girls VS Boys,ecc.ecc

Ultima modifica di prazision : 18-04-2005 alle 21:44.
prazision è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare Cineca inaugura Pitagora, il supercomputer Lenov...
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA Mova Z60 Ultra Roller Complete: pulisce bene gra...
Renault Twingo E-Tech Electric: che prezzo! Renault Twingo E-Tech Electric: che prezzo!
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media Il cuore digitale di F1 a Biggin Hill: l'infrast...
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica DJI Osmo Mobile 8: lo stabilizzatore per smartph...
HONOR 500 Pro, scheda tecnica confermata...
GeForce NOW si prepara a vivere un mese ...
Exynos 2600: temperature più bass...
Apple si ispirerà a Nothing? Back...
Da Intel ad AMD, il grande salto di Kulk...
Velocità 12 volte superiore a que...
Una piccola Morte Nera è gi&agrav...
Sei frodi che minacciano gli utenti nel ...
BioShock 4: Take-Two rassicura sullo svi...
Tesla, Musk promette FSD 'quasi pronto' ...
BioWare conferma: il nuovo Mass Effect &...
5 robot aspirapolvere di fascia alta in ...
Xiaomi Redmi Note 14 5G a 179€ è ...
Veri affari con gli sconti de 15% Amazon...
Tutti gli iPhone 16 128GB a 699€, 16e a ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 04:14.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v