Qual è la migliore pratica per usare "get" nei nomi dei metodi?
Domanda
Ho notato in molti punti di Java (incluso C #) che molti "getter" i metodi sono preceduti da " get " mentre molti altri non lo sono. Non ho mai notato alcun tipo di modello che Sun sembra seguire. Quali sono alcune linee guida o regole per l'utilizzo di " get " con nomi di metodi getter?
Soluzione
Dipende dalla semantica. Sì, C # ha " proprietà " che ti dà uno stub "metodo" get / set ... ma funzioni (... "metodi " ...) in .NET Framework che iniziano con " Get " si suppone che indichi lo sviluppatore sul fatto che alcune operazioni stanno avvenendo al solo scopo di ottenere alcuni risultati.
Potresti pensare che sia strano e dire " perché non usare semplicemente il tipo di ritorno per capire le persone in? " ;, e la risposta è semplice. Pensa ai seguenti metodi:
public Person CreatePerson(string firstName, string lastName) {...}
Solo con il nome di quel metodo, puoi probabilmente immaginare che ci saranno attività di database coinvolte e quindi una persona di nuova creazione "quotata"; verrà restituito.
ma, che dire di questo:
public Person GetPerson(string firstName, string lastName) {...}
Solo con il nome del metodo , puoi probabilmente supporre che un 100% "sicuro" è in corso il recupero di una persona da un database.
Non chiameresti mai " CreatePerson " più volte ... ma dovresti sentirti sicuro di chiamare " GetPerson " tutto il tempo. (non dovrebbe influire sullo "stato" dell'applicazione).
Altri suggerimenti
" ottenere " e "impostare" la coppia di prefissi in Java viene utilizzata originariamente come convenzione per indicare il java bean. Successivamente, diventa solo una convenzione di incapsulamento, poiché Java, a differenza di C #, non ha proprietà appropriate.
La migliore pratica in Java è usare i prefissi get e set per le proprietà.
Framework, librerie di tag, ecc. cercheranno metodi con quei prefissi e li useranno come proprietà.
Quindi, se hai una classe java come questa ...
public class User{
private String name;
public String getName(){ return name;}
public void setName(String name){ this.name = name; }
}
.. con struts-tag (o qualsiasi altra libreria di tag basata su ognl) accederai alla proprietà name con user.name
.
Anche il framework Spring utilizza questa convenzione nei file di configurazione xml.
Java non supporta (ancora) le proprietà. Getter e setter sono un espediente per aggirare questo. Altre lingue - incluso C # - supportano le proprietà e dovresti invece usarle. Questa non è solo una "best practice" o cosa: la serializzazione in C # si baserà su proprietà, non su getter e amp; setter, quindi non utilizzare le proprietà potrebbe portare a tutti i tipi di problemi in futuro se è necessario serializzare le classi.
Il vantaggio delle proprietà è che rendono il codice più leggibile. Qualcosa come
obj.setX(10);
in Java, diventa
obj.X = 10;
Eppure dietro le quinte, X è un metodo, piuttosto che essere una variabile e quindi può eseguire controlli di input sporchi ecc.
Personalmente mi piace la seguente regola:
- Utilizza il prefisso
get
ogni volta che il valore è direttamente modificabile con un metodoset
corrispondente - Rilascia il prefisso
get
in situazioni in cui il valore è qualcosa che non puoi impostare direttamente come proprietà (ovvero non esiste un metodo setXXX equivalente)
La logica del secondo caso è che se il valore non è realmente una "proprietà" impostabile dall'utente. come tale, quindi non dovrebbe aver bisogno di una coppia di metodi get / set. Un'implicazione è che se questa convenzione viene seguita e vedi un metodo getXXX, puoi anche supporre l'esistenza di un metodo setXXX.
Esempi:
-
String.length ()
- poiché le stringhe sono immutabili, la lunghezza è un valore di sola lettura -
ArrayList.size ()
- le dimensioni cambiano quando vengono aggiunti o rimossi elementi, ma non è possibile impostarlo direttamente
Di solito era il caso che le API spesso esponessero proprietà di sola lettura senza il prefisso get
: String.length ()
e persino il nuovo Buffer.capacity ()
essendo esempi ragionevoli.
Il lato positivo di questo è che c'è meno lanugine coinvolta. Il rovescio della medaglia è che tutto ciò che cerca di determinare automaticamente le proprietà in base alle convenzioni non le scoprirà. Personalmente tendo di sbagliare a parte l'inclusione del prefisso.
Ovviamente, in C # è per lo più irrilevante in quanto vi sono "reali" proprietà comunque :)
Dipende. Spesso sono informazioni ridondanti, anche in lingue senza proprietà.
In C ++, invece di una coppia getAttr () / setAttr (), è comune fornire due overload di una funzione Attr (): void Attr (Foo f); // Il setter Foo Attr (); // Il getter
In Java, è pratica comune aggiungere prefisso get / set. Devo dire che la migliore pratica è quella di seguire ciò che è standard nella tua lingua. In Java, le persone si aspettano di vedere i prefissi get / set, quindi ometterli potrebbe confondere le persone, anche se non sono strettamente necessarie.
Anche l'obiettivo C 2.0 usa le proprietà, usando la stessa sintassi del punto.
Prima di ciò, utilizzava uno schema di denominazione leggermente diverso per getter e setter (che, naturalmente, può ancora essere usato con proprietà o per semplici vecchi attributi).
value = [obj attr];
[obj setAttr:value];
[obj getAttr:&value];
Cioè, get viene utilizzato in un modo diverso. Non restituisce un valore, ma memorizza il risultato nella variabile passata.
Il tipico getter ha lo stesso nome dell'attributo, il setter è l'attributo prefissato da set (secondo la convenzione di Java). Queste convenzioni sono utilizzate dal sistema KVO (Key-Value Observation), quindi dovrebbero essere rispettate.
Solo un breve addendum: un'altra convenzione è che per i getter dei campi booleani con prefisso " è " invece di " get " ;, ad es. bool isEnabled () {return enabled; }