La public final è completamente (non) ok in campi enum costanti?

4

Quando eseguo enum che contengono alcuni campi, come il mio Settings enum, mi piace renderli pubblici finali per evitare un sacco di ( e ) sequenze di tasti:

public enum Settings {
  SETTING_TEST("bool_setting1", false),
  USERNAME("user_name", "me")
  ;

  public final String name;
  public final Object default_val;
  Setnames(String n, Object d) {
    name = n;
    default_val = d;    
  }
}

Questo enum viene quindi applicato per cercare (o impostare le impostazioni di default) in qualche hashmap (incapsulato in una classe più sofisticata). Questo design consente di controllare i nomi delle impostazioni sull'intero progetto (poiché i nomi dei enum possono essere rifatti, a differenza delle stringhe).

Tuttavia, il mio insegnante mi ha avvertito di questo progetto e ci sono alcune risposte che suggeriscono che puoi pentirti di aver progettato il tuo progetto con public final senza incapsulamento.

Non sto solo chiedendo regole e convenzioni, ma anche la tua esperienza (il centro assistenza non dire qualcosa di negativo sulla richiesta di opinioni, quindi lo faccio). Anche se espanderei volentieri la domanda su altre lingue che supportano le funzionalità in questione, non sono sicuro che ciò non renderebbe la domanda troppo ampia - motivo per cui penso che dovremmo limitarci solo a Java.

Modifica

La SE GUI mi chiede di spiegare in che modo la mia domanda è diversa da quella a cui mi sono collegato. Altre persone hanno già indicato nei commenti la differenza, ma ripetiamolo:

La maggior parte delle risposte sull'altra domanda sottolinea problemi non applicabili alle enumerazioni. Spesso usiamo incapsulamento getXXX per consentire alle classi di estendere correttamente la nostra classe. Ma non possiamo estendere da enum . Generalmente, nonostante la sintassi simile, le enumerazioni sono sostanzialmente diverse dalle classi e dalle interfacce .

    
posta Tomáš Zato 09.03.2015 - 11:13
fonte

2 risposte

5

La mia opinione personale è che public final è generalmente soddisfacente ovunque , non solo per enumerazione.

Nel mio libro, ci sono solo due motivi per non utilizzare public final , e questi sono:

  • Consentire modifiche future che potrebbero richiedere la modifica della natura dei campi mantenendo la compatibilità binaria con codice esterno. (Un getter permetterebbe questo.)

  • Digitando 'get' e lasciando che autocomplete mostri tutto ciò che posso leggere da un oggetto senza dover scorrere verso l'alto e verso il basso nell'elenco di completamento automatico per vedere se oltre ai metodi getter ci sono anche tutti i campi public final che io può leggere (i cui nomi presumibilmente non iniziano con get .)

Per quanto riguarda i punti della risposta a cui ti sei collegato, nessuno di questi è applicabile alle enumerazioni.

Quindi, anche se non sei d'accordo sul fatto che public final sia generalmente soddisfacente ovunque , comunque, almeno per le enumerazioni, è davvero molto bello.

    
risposta data 09.03.2015 - 15:08
fonte
4

public final è OK nel mio libro quando stai implementando qualcosa che è solo un contenitore di dati. Rendendo tutti i campi public final è chiaro che una volta che l'oggetto è stato costruito, tutti i campi sono disponibili e non ci saranno affari divertenti dietro le quinte (inizializzazione pigra, valori calcolati, valori recuperati da I / O o qualsiasi altra cosa .)

Il solito ragionamento dietro i getter è che un giorno potresti aver bisogno che il tuo oggetto sia un po 'più "intelligente". Ma ti sei già impegnato a utilizzare un enum , il che presuppone che tutti i dati siano staticamente disponibili e che i tuoi oggetti abbiano una semantica del valore. Scommetterei che se hai mai bisogno di annullare la decisione di utilizzare i campi public final , un enum probabilmente non sarà più la scelta giusta.

I getters una tantum sono assolutamente necessari quando la classe che stai scrivendo fa parte dell'API pubblica di una libreria disponibile al pubblico, perché vuoi mantenere la compatibilità binaria a tutti i costi. Non vuoi introdurre un cambiamento incompatibile all'indietro per qualcosa di così semplice come cambiare un getter.

    
risposta data 09.03.2015 - 15:39
fonte

Leggi altre domande sui tag