Pagina 1 di 8 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 75
  1. #1
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315

    valutazione codice "migliore"

    Un esercizio che ho svolto chiede la costruzione della classe TestQuadrato contenente un metodo main() che istanzi un oggetto di tipo Quadrato con lato di valore 5. Successivamente bisogna stampare perimetro e area dell'oggetto appena creato.
    La mia soluzione è la seguente:
    codice:
    public class TestQuadrato
    {
        public static void main(String args[])
        {
            Quadrato oggetto = new Quadrato(5);
        }
    }
    codice:
    public class Quadrato
    {
        public int lato;
    
        public Quadrato(int lato)
        {
            int perimetro = lato * 4;
            int area = lato * lato;
            System.out.println("il perimetro è: " + perimetro);
            System.out.println("l'area è: " + area);        
        }    
    }
    mentre la soluzione proposta dal manuale è questa:
    codice:
    public class TestQuadrato {
        public static void main(String args[]) {
            Quadrato quadrato = new Quadrato();
            quadrato.lato = 5;
            int perimetro = quadrato.perimetro();
            System.out.println(perimetro);
            int area = quadrato.area();
            System.out.println(area);
        }
    }
    codice:
    public class Quadrato {
        public int lato;
        public int perimetro() {
            int perimetro = lato * 4;
            return perimetro;
        }
        public int area() {
            int area = lato * lato;
            return area;
        }
    }
    La mia soluzione funziona però vorrei capire se concettualmente è più corretto fare le "operazioni" all'interno del metodo main (come fatto nella soluzione proposta dal manuale) oppure all'interno del costruttore (come fatto da me).

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    La soluzione corretta è quella proposta dal manuale.
    Un costruttore è un particolare "metodo" che serve, appunto, a costruire (nel senso di rendere consistente) un oggetto. Un costruttore, solitamente, si occupa di valorizzare i campi di un oggetto e di fare piccole operazioni preliminari, ma non dovrebbe avere codice "operativo".

    Il calcolo dell'area del quadrato dovrebbe essere relegato, appunto, ad un metodo idoneo, che possa essere facilmente invocato da chi usa la classe. Se io costruisco un oggetto Quadrato è perchè intendo lavorare con quell'oggetto... uno dei lavori che vorrò fare è, appunto, calcolare l'area o il perimetro di tale quadrato. Queste sono operazioni che io posso voler fare, ma che non debbono per forza essere fatte a tutti i costi. Se voglio solo ottenere l'area, non ha senso che calcoli anche il perimetro... se metto queste operazioni nel costruttore, verranno sempre eseguite ad ogni istanziazione dell'oggetto. Lavoro inutile, che comunque non posso usare perchè come l'hai fatto tu non funziona: la classe non mi restituisce alcuna informazione utile... semplicemente fa un calcolo e lo stampa a video... e se io volessi farci qualcos'altro (che alla classe non interessa)? Ad esempio, se avessi 4 quadrati e volessi calcolare la somma delle loro aree?


    Rifletti su questa cosa.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Quindi se non ho capito male una soluzione concettualmente corretta potrebbe essere questa:
    codice:
    public class Test
    {
        public static void main(String args[])
        {
            Rettangolo rettangolo1 = new Rettangolo(5,6);
            System.out.println("il perimetro del rettangolo 1 è: " + rettangolo1.perimetro());
            System.out.println("l'area del rettangolo 1 è: " + rettangolo1.area());
            Rettangolo rettangolo2 = new Rettangolo(7,8);
            System.out.println("il perimetro del rettangolo 2 è: " + rettangolo2.perimetro());
            System.out.println("l'area del rettangolo 2 è: " + rettangolo2.area());
        }    
    }
    codice:
    public class Rettangolo
    {
        public final int NUMERO_LATI_UGUALI = 2;
        public int base;    
        public int altezza;
    
        public Rettangolo(int b, int a)
        {
            base = b;
            altezza = a;
        }
    
        public int perimetro()
        {
            int perimetro = (base + altezza) * NUMERO_LATI_UGUALI; 
            return (perimetro);
        }
    
        public int area()
        {
            int area = (base * altezza);
            return (area);
        }
    }

    Giusto?


    p.s. ho fatto l'esempio del rettangolo ma è analogo al quadrato.

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    Sì, corretto.
    Come pura puntualizzazione (al manuale, non a te), i metodi di questo tipo (che restituiscono qualcosa) si chiamano "getter" e dovrebbero, appunto, chiamarsi getXXX(). Nel tuo caso, quindi, i due metodi dovrebbero chiamarsi, rispettivamente, getPerimetro() e getArea().

    E' molto più di una banale "convenzione": è diventata una specifica per quanto riguarda i Java Bean.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    grazie per la precisazione. immagino comunque che siano stati scelti dei nomi più semplici per facilitare l'apprendimento.

  6. #6
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Vorrei un vostro parere su un altro esercizio.
    La traccia è la seguente:
    Creare una classe con un metodo main() che selezioni i primi 10 numeri divisibili per 3 e li stampi dopo averli concatenati con una stringa in modo tale che l'output del programma sia:
    Numero multiplo di 3 = 3
    Numero multiplo di 3 = 6
    Numero multiplo di 3 = 9
    ...
    La mia soluzione è questa:
    codice:
    public class Divisibili
    {
        public static void main(String args[])
        {
            for(int i=1; i<=30; i++)
            {
                if (i%3!=0)
                {
                    continue;
                }
                else
                {
                    System.out.println("Numero multiplo di 3 = " + i);
                }
            }
        }
    }
    mentre quella del manuale è questa:
    codice:
    public class Esercizio4h {
               public static void main(String args[]) {
                              for (int i = 1, j = 1; j <= 10; i++) {
                                         if (i % 3 == 0){
                                                   System.out.println("Numero multiplo di 3 = " + i);
                                                   j++;
                                         }
                              }
               }
    }
    Voi che dite? Qual è la soluzione corretta?

  7. #7
    Utente di HTML.it
    Registrato dal
    May 2012
    Messaggi
    213
    A mio parere le due soluzione sono esattamente uguali.
    Se tu provassi a togliere l'else e mettere il codice che c'è dentro nel tuo if cambiandogli la condizione con (i % 3 == 0) otterresti proprio un codice equivalente a quello proposto dal tuo manuale.
    Diciamo che il tuo codice è ridondante poichè quel continue può essere tranquillamente tolto.

  8. #8
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    Una nota ti faccio a priori: un'unica soluzione ad un problema non esiste, se il programma dato un input produce l'output che ti aspetti, va bene.
    A dire il vero poi nessuno dei due rispetta realmente la consegna (voleva un'unica stringa), ma possiamo passare oltre, visto che a video è impossibile capire se sono 10 println differenti o è un'unica print di uno stringone.
    La migliore soluzione varia a seconda di quale aspetto/tecnica era richiesto tu mettessi l'attenzione e a seconda se vengono rispettati o meno i paradigmi del linguaggio di programmazione (es. se fai codice contorto o poco manutenibile) scelto.
    RTFM Read That F*** Manual!!!

  9. #9
    Utente di HTML.it
    Registrato dal
    Oct 2014
    Messaggi
    315
    Capito. Diciamo che lo scopo di questa discussione è capire più che altro se il codice che produco è accettabile e conforme con i paradigmi di programmazione.

    Giusto per chiarezza vi posto un altro esercizio.
    Considerare la classe:
    codice:
    import java.util.Scanner;
    
    public class ProgrammaInterattivo {
        public static void main(String args[]) {
            Scanner scanner = new Scanner(System.in);
            String stringa = "";
            System.out.println("Digita qualcosa e batti enter, oppure " + "scrivi \"fine\" per terminare il programma");
            
            while(!(stringa = scanner.next()).equals("fine")) {
                System.out.println("Hai digitato " + stringa.toUpperCase() + "!");
            }
    
            System.out.println("Fine programma!");
        }
    }
    ProgrammaInterattivo legge l’input da tastiera mediante la classe Scanner del package java.util. Il metodo next() usato nel costrutto while (con una sintassi complessa che comprende anche l’assegnazione alla variabile stringa) è un metodo bloccante che legge l’input da tastiera sino a quando si preme il tasto “enter” (invio). Il programma termina quando si digita la parola “fine”.
    Modificare il programma precedente in modo tale che diventi un moderatore di parole, ovvero che censuri alcune parole digitate.
    la mia soluzione è questa:
    codice:
    import java.util.Scanner;
    
    public class Moderatore
    {
        public static void main(String args[])
        {
            Scanner scanner = new Scanner(System.in);
            String stringa = "";
            System.out.println("Digita qualcosa e batti enter, oppure " + "scrivi \"fine\" per terminare il programma");
            while(!(stringa = scanner.next()).equals("fine"))
            {
                if(stringa.equals("perbacco") || stringa.equals("stupidino") || stringa.equals("giocondo"))
                {
                    System.out.println("parola censurata");    
                        
                }
                else
                {
                    System.out.println("Hai digitato " + stringa.toUpperCase() + "!");
                    continue;                                                
                }
            }
            System.out.println("Fine programma");
        }
    }
    la soluzione proposta dal manuale è questa:
    codice:
    import java.util.Scanner;
    
    public class Moderatore {
        public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        String stringa = "";
        System.out.println("Digita qualcosa e batti enter, oppure " + "scrivi \"fine\" per terminare il programma");
    
        while (!(stringa = scanner.next()).equals("fine")) {
            stringa = moderaStringa(stringa);
            System.out.println("Hai digitato " + stringa.toUpperCase() + "!");
        }
        System.out.println("Fine programma!");
    }
    
    private static String moderaStringa(String stringa) {
        switch (stringa) {
            case "accipicchiolina":
            case "perbacco":
            case "stupidino":
            case "giulivo":
            case "giocondo":
            case "perdindirindina":
                stringa = "CENSURATA!";
                break;
            default:
                break;
        }
        return stringa;
    }
    
    }
    Cosa ne pensate?

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2007
    Messaggi
    4,157
    il fatto di racchiudere il controllo della stringa in un altro metodo (puoi anche non farlo) è indice della voglia dell'autore di parlare di "interazioni tra oggetti" e di scrivere metodi piccoli, che si preoccupino di un solo aspetto della problematica (nel caso specifico capire se la stringa è valida o meno).

    La soluzione del libro la preferisco per due motivi:
    1. isoli la parte del controllo (che puoi cambiare come ti pare dentro il metodo senza interferire con chi lo usa
    2. sfrutta la feature da java 7 in poi dello switch su stringhe

    scrivendo codice più elegante
    RTFM Read That F*** Manual!!!

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.