Domanda

Di recente ho iniziato a lavorare in Java e mi è stato presentato il mondo selvaggio e folle di getter e setter per tutto. All'inizio l'ho odiato, ma mi sono subito abituato. Troppo abituato.

Ultimamente ho trascorso molto tempo a pensare di più al design di classe. Una delle cose che sto cercando di fare è evitare la trappola di fare getter e setter per tutto. Tuttavia, gran parte del lavoro che svolgo riguarda entità che sono principalmente contenitori di dati e non sono sicuro che getter e setter siano effettivamente inappropriati in questi casi.

Ecco un semplice esempio usando le proprietà pubbliche.

class Space {
    public String name;
    public String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
}

Ecco un semplice esempio usando proprietà private e usando getter e setter.

class Space {
    private String name;
    private String description;
    Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }
    public String getName() {
        return this.name;
    }
    public void setName(final String name) {
        this.name = name;
    }
    public String getDescription() {
        return this.description;
    }
    public void setDescription(final String description) {
        this.description = description;
    }
}

In questi esempi, entrambi i campi name e description dovrebbero poter essere modificati.

Sento che l'esempio getter / setter è più chiaro e nasconde i dettagli di implementazione di cosa sono name e description . Consentirebbe anche la convalida sul set in seguito, se necessario.

Ho letto diverse discussioni sul fatto che getter e setter siano malvagi e / o un anti-schema, ma sembra davvero che quelli potrebbero non essere applicabili a questa situazione.

Forse ci sono alcune opzioni che non ho ancora preso in considerazione. Sono aperto a suggerimenti!

È stato utile?

Soluzione

Per dirla in parole povere:

  • Hai bisogno di getter per tutti i campi che devono essere letti dall'esterno.
  • Sono necessari setter per tutti i campi che devono essere scritti dall'esterno.

Questo può essere al 100%, ma il più delle volte è inferiore.

Altri suggerimenti

La prima versione (proprietà pubbliche) non è una buona idea. Il secondo è migliore. Come direbbe Josh Bloch, " favor immutability " :

public class Space {
    private final String name;
    private final String description;

    public Space(final String name, final String description) {
        this.name = name;
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }
}

Detto questo, tenditori e setter tendono a essere abusato .

Hai sentito che spesso i "get / setter sono troppo semplificati". Nessuno (spero) davvero significa che c'è qualcosa che non va negli oggetti dati. Penso che la vera idea sia:

" Getter / setter sono cattivi, ad eccezione degli oggetti di archiviazione di dati semplici " che di per sé è solo un evangelismo di " tell non ask " ;.

Idealmente se una classe ha getter e setter, questo è tutto che dovrebbe avere.

Questo è comunque l'argomento. Non sono sicuro di essere d'accordo.

Mentre il modello di accesso aiuta a nascondere i dettagli di implementazione di una classe (ad es. l'uso di una tabella hash per memorizzare gli attributi per risparmiare memoria su classi scarsamente usate), può essere molto dettagliato da implementare (il tuo esempio ha 12 righe in più con gli accessori). Ecco perché C # ha una sintassi di proprietà speciale, che consente di specificare in modo conciso gli accessor predefiniti:

class Space {
    public String Name { get; set; }
    public String Description { get; set; }
    Space(final String name, final String description) {
        this.Name = name;
        this.Description = description;
    }
}

I moduli alternativi possono aggiungere identificatori di accesso e / o codice:

private String _name;
public String Name {
    get { if (_name == null) FetchName(); return _name; }
    private set { _name = value; }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top