Uso dei getter pubblici finali piuttosto che privati

48

Vedo i POJO immutabili scritti in questo modo:

public class MyObject {
    private final String foo;
    private final int bar;

    public MyObject(String foo, int bar) {
        this.foo = foo;
        this.bar = bar;
    }

    public String getFoo() {
        return foo;
    }

    public int getBar() {
        return bar;
    }
}

Eppure tendo a scriverle così:

public class MyObject {
    public final String foo;
    public final int bar;

    public MyObject(String foo, int bar) {
        this.foo = foo;
        this.bar = bar;
    }
}

Nota che i riferimenti sono definitivi, quindi l'oggetto è ancora immutabile. Mi consente di scrivere meno codice e consente l'accesso più breve (di 5 caratteri: get e () ).

L'unico svantaggio che posso vedere è se vuoi cambiare l'implementazione di getFoo() in fondo alla strada per fare qualcosa di pazzo, non puoi. Ma realisticamente, questo non accade mai perché l'Oggetto è immutabile; puoi verificare durante l'istanziazione, creare copie difensive immutabili durante l'istanziazione (vedi ad esempio% co_de di Guava), e ottenere gli oggetti ImmutableList o foo pronti per la chiamata di bar .

Ci sono degli svantaggi che mi mancano?

Modifica

Suppongo che un altro svantaggio che mi manca sono le librerie di serializzazione che usano il reflection sui metodi che iniziano con get o get , ma questa è una pratica piuttosto terribile ...

    
posta Cory Kendall 18.03.2013 - 02:00
fonte

4 risposte

37

Quattro svantaggi a cui posso pensare:

  1. Se vuoi avere una forma di sola lettura e mutevole della stessa entità, un modello comune è di avere un'entità di classe immutabile che espone solo gli accessor con le variabili membro protette, quindi crea un'Entità Mutevole che la estende e aggiunge setter. La tua versione lo impedisce.
  2. L'uso di getter e setter aderisce alla convenzione JavaBeans. Se vuoi utilizzare la tua classe come bean nelle tecnologie basate sulle proprietà, come JSTL o EL, devi esporre i getter pubblici.
  3. Se desideri modificare l'implementazione per ricavare i valori o cercarli nel database, devi rifattorizzare il codice cliente. Un approccio di accesso / mutatore ti consente di modificare solo l'implementazione.
  4. Almeno stupore - quando vedo variabili di istanza pubbliche, cerco immediatamente chi potrebbe modificarlo e mi preoccupo di aprire la scatola di Pandora perché l'incapsulamento è stato perso. link

Detto questo, la tua versione è decisamente più concisa. Se si trattasse di una classe specializzata che viene utilizzata solo all'interno di un pacchetto specifico (forse l'ambito del pacchetto è una buona idea qui), allora potrei considerarlo come una tantum. Ma non vorrei esporre API importanti come questa.

    
risposta data 18.03.2013 - 02:57
fonte
24

Sbarazzati anche dei getter / setter e stai bene!

Questo è un argomento molto controverso tra i programmatori Java.

Comunque, ci sono due situtation in cui uso variabili pubbliche invece (!) di getter / setter:

  1. finale pubblico Per me questo segnale "Sono immutabile" molto meglio di un semplice getter. La maggior parte degli IDE indicano il modificatore finale con una "F" durante il completamento automatico. A differenza di getter / setter, in cui è necessario cercare l'assenza di un setXXX.
  2. public non-final mi piace per le classi di dati. Espongo solo tutti i campi pubblicamente. Nessun getter, setter, costruttori. No niente. Meno di un pojo. Per me questo immediatamente segnala "guarda, sono stupido, tengo i dati, tutto qui, è il tuo lavoro mettere i dati giusti dentro di me". GSON / JAXB / etc. gestire queste classi bene. Sono felici di scrivere. Non c'è dubbio sul loro scopo o capacità. E soprattutto: sai che non ci sono effetti collaterali quando cambi una variabile. IMHO questo si traduce in modelli di dati molto concisi con poche ambiguità, mentre getter e setter hanno questo enorme problema dove a volte accade la magia all'interno di essi.
risposta data 05.11.2014 - 19:17
fonte
9

In parole semplici:

  • Violi l'incapsulamento per salvare poche righe di codice. Quello sconfigge lo scopo dell'OOD.
  • Il codice cliente sarà hard coupled ai nomi dei membri della tua classe. L'accoppiamento è cattivo. L'intero scopo dell'OOD sta impedendo l'accoppiamento
  • Sei anche molto sicuro che la tua classe non avrà mai bisogno di essere mutabile. Le cose cambiano. Il cambiamento è l'unica cosa costante.
risposta data 28.05.2013 - 16:31
fonte
6

Un possibile svantaggio che posso vedere è che sei legato alla rappresentazione interna dei dati nella classe. Questo probabilmente non è un grosso problema, ma se si usano i setter e si decide che foo e bar saranno restituiti da qualche altra classe definita da qualche altra parte, le classi che consumano MyObject non saranno obbligate a cambiare. Dovresti solo toccare MyObject. Tuttavia, se utilizzi i valori nudi, dovresti toccare ovunque il tuo MyObject utilizzato.

    
risposta data 18.03.2013 - 02:38
fonte

Leggi altre domande sui tag