La 12-String dovrebbe essere nella sua classe e perché?

3

Questa domanda riguarda un progetto di compiti a casa nella mia prima classe di programmazione Java (programma online).

L'incarico consiste nel creare una classe "strumento a corda" usando (tra le altre cose) una serie di nomi String che rappresentano nomi di stringhe di strumenti ("A", "E", ecc.). L'idea per la 12-stringa va oltre lo scopo dell'assegnazione (non deve essere inclusa affatto) ma ora che ci ho pensato, voglio capire come farlo funzionare.

Una parte di me sembra che la 12-String dovrebbe avere una sua classe, ma un'altra parte di me ritiene che dovrebbe essere nella classe della chitarra perché è una chitarra. Suppongo che questo diventerà chiaro mentre progredisco ma ho pensato di vedere che tipo di risposta ottengo qui.

Inoltre, perché chiederebbero una stringa [] per i nomi delle stringhe dello strumento? Sembra un char [] ha più senso.

Grazie per qualsiasi approfondimento.

Ecco il mio codice finora (è un work in progress):

public class Guitar {


private int numberOfStrings = 6;
private static int numberOfGuitars = 0;
private String[] stringNotes = {"E", "A", "D", "G", "B", "A"};
private boolean tuned = false;
private boolean playing = false;

public Guitar(){
    numberOfGuitars++;
}

public Guitar(boolean twelveString){
    if(twelveString){
        stringNotes[0] = "E, E";
        stringNotes[1] = "A, A";
        stringNotes[2] = "D, D";
        stringNotes[3] = "G, G";
        stringNotes[4] = "B, B";
        stringNotes[5] = "E, E";
        numberOfStrings = 12;
    }
}

public int getNumberOfStrings() {
    return numberOfStrings;
}

public void setNumberOfStrings(int strings) {
    if(strings == 12 || strings == 6) {
        if(strings == 12){
            stringNotes[0] = "E, E";
            stringNotes[1] = "A, A";
            stringNotes[2] = "D, D";
            stringNotes[3] = "G, G";
            stringNotes[4] = "B, B";
            stringNotes[5] = "E, E";
            numberOfStrings = strings;
        }
        if(strings == 6)
            numberOfStrings = strings;
    }//if
    else
        System.out.println("***ERROR***Guitar can only have 6 or 12 strings***ERROR***");
}

public void getStringNotes() {
        for(int i = 0; i < stringNotes.length; i++){
            if(i == stringNotes.length - 1)
                System.out.println(stringNotes[i]);
            else
                System.out.print(stringNotes[i] + ", ");
        }//for
}
    
posta MayNotBe 12.12.2012 - 04:35
fonte

2 risposte

5

Le decisioni di progettazione come quella che menzioni dovrebbero essere guidate dai requisiti. Dato che sembra un puro esercizio di modellazione, non dovresti preoccuparti troppo.

Come regola generale per meno mal di testa futuri, preferisci le classi immutabili, quindi mi piacerebbe sbarazzarmi di quel setter.

Userei anche le enumerazioni anziché i char array.

Infine prova a non ripetere blocchi di codice. Questo aumenta la probabilità di bug e rende più difficile capire il codice.

Ah, e non dimenticare di documentare il tuo codice: cosa fa un metodo, precondizioni, postcondizioni, eccezioni.

    
risposta data 12.12.2012 - 05:03
fonte
5

Questo va un po 'oltre la classe Java di introduzione, ma ...

Le sottoclassi possono mandarti giù dei buchi di coniglio piuttosto profondi. Il numero di stringhe è solo l'inizio. Ibrido acustico, elettrico o acustico-elettrico? Se il corpo elettrico, solido o cavo? Quanti pickup? Bobina singola o doppia (humbucker)? Ponte fisso o galleggiante? Se acustica, classica o in acciaio (le classiche hanno un collo più largo e usano corde di nylon)? E ancora e ancora e ancora. La creazione di una classe o sottoclasse separata per ogni tipo di chitarra porta rapidamente alla follia (e non siamo nemmeno entrati nei bassi o in altri tipi di strumenti a corda).

Invece di provare a tracciare tutte queste informazioni creando una serie di sottoclassi di Guitar , un approccio migliore è quello di delegare a tracciare tali informazioni ad altre classi. Ad esempio, possiamo creare una classe Tuning che tiene traccia del numero di stringhe (o corsi, grazie a Blrfl) e delle loro accordature. Possiamo creare una classe Body che tiene traccia se è un corpo solido o vuoto, una classe Pickup per tracciare il tipo di pickup, una classe Neck per descrivere larghezza, raggio e lunghezza della scala del collo, ecc. Quindi componi tutte queste classi separate in una Guitar class 1 :

public class Guitar {
  Body bodyStyle;
  Neck neckStyle;
  Tuning tuning;
  ...
};

Si noti che ciascuna di queste classi può anche delegare alcune informazioni ad altre classi (ad esempio, la classe Tuning potrebbe delegare informazioni di tracciamento su singole corde di chitarra (calibro (spessore), ferita / svolta, composizione, ecc.) una classe GuitarString .

In questo modo, possiamo usare la stessa classe Guitar per specificare molti tipi diversi di chitarre:

Guitar g = new Guitar(new Body (/* body parameters */),
                      new Neck (/* neck parameters */),
                      new Tuning (/* tuning parameters */),
                      ...);

In generale, vuoi mantenere le tue gerarchie di classe piuttosto superficiali e usare la delega il più possibile (quando senti o leggi qualcuno che dice "favorisci la composizione sull'ereditarietà", questo è ciò che intendono). Questo ti dà più flessibilità e riduce il tuo mal di testa di manutenzione.

Sapere dove disegnare la linea è una questione di esperienza e il problema a portata di mano. È possibile andare fuori bordo in entrambi i modi. Ci sono momenti in cui si desidera sottoclasse perché si desidera applicare un'interfaccia o un comportamento specifico su tutte le istanze e ci sono momenti in cui lo sforzo di delegare a un'altra classe non vale la pena.

1: È passato più di un anno da quando ho dovuto scrivere qualsiasi Java, quindi non posso scrivere esempi dettagliati senza avvitare qualcosa su
risposta data 12.12.2012 - 16:24
fonte

Leggi altre domande sui tag