Perché attenersi rispettivamente a get-set e non a car.speed() e car.speed(55)?
-
20-09-2019 - |
Domanda
A parte la chiarezza inequivocabile, perché dovremmo attenerci a:
car.getSpeed()
E car.setSpeed(55)
quando potrebbe essere usato anche questo:car.speed()
E car.speed(55)
So che get() e set() sono utili per mantenere gestibili eventuali modifiche al membro dati mantenendo tutto in un unico posto.
Inoltre, ovviamente, lo capisco car.speed()
E car.speed(55)
sono i Stesso funzione, il che lo rende sbagliato, ma poi in PHP e anche in Zend Framework, la stessa azione viene utilizzata per GET, POST, postback.
In VB e C# ci sono "proprietà", e sono usate da molti, con grande disgusto dei puristi che ho sentito, e ci sono cose in Ruby come 5.times
E .each
, .to_i
eccetera.
E ci sono il sovraccarico degli operatori, l'ereditarietà multipla, le funzioni virtuali in C++, alcune combinazioni delle quali potrebbero far impazzire chiunque.
Voglio dire che ci sono così tanti paradigmi e modi in cui le cose vengono fatte che sembra strano che nessuno abbia provato la particolare combinazione che ho menzionato.
Per quanto mi riguarda, la ragione è che lo è breve e più pulito da leggere il codice.
Mi sbaglio molto, leggermente, è semplicemente strano e quindi non utilizzato, o cos'altro?
Se decido ancora di rimanere corretto, potrei usare car.speed()
E car.setSpeed(55)
.
È sbagliato in qualche modo (omettendo semplicemente "get")?
Grazie per eventuali spiegazioni.
Soluzione
Se ho chiamato car.speed (), potrei pensare che io sto dicendo la macchina alla velocità, in altre parole, per aumentare la velocità e rompere il limite di velocità. Non è chiaramente un getter.
Alcune lingue consentono di dichiarare gli oggetti const, e poi si limita solo a funzioni che non modificano i dati dell'oggetto chiamando. Quindi è necessario avere funzioni separate per la modifica e leggere le operazioni. Mentre si potrebbe utilizzare sovraccarichi sulla paramaters di avere due funzioni, penso che sarebbe fonte di confusione.
Inoltre, quando si dice che è più chiaro da leggere, posso sostenere che devo fare uno sguardo in avanti per capire come leggerlo:
car.speed()
ho letto "velocità della vettura ..." e poi vedo non c'è un numero così ho rivedere e penso "ottenere velocità della vettura".
car.getSpeed()
ho letto "per questa vettura, ottenere velocità"
car.setSpeed(55)
ho letto "per questa vettura, impostare la velocità a 55"
Sembra che tu abbia fondamentalmente citato altre caratteristiche del linguaggio come fonte di confusione, e poi utilizzato, che come difesa per fare getter / setter più confusa? Sembra quasi stanno ammettendo che ciò che avete proposto è più confusa. Queste caratteristiche sono a volte confuse a causa di come general purpose sono. A volte astrazioni possono essere più confuso, ma alla fine hanno spesso servire allo scopo di essere più riutilizzabile. Penso che se si voleva discutere in favore della velocità () e la velocità (55), che ci si vuole mostrare come ciò possa consentire nuove possibilità per il programmatore.
D'altra parte, C # ha qualcosa di simile a ciò che si descrive, dal momento che le proprietà comportano in modo diverso come un getter o setter a seconda del contesto in quello che sono utilizzati:
Console.WriteLine(car.Speed); //getter
car.Speed = 55 //setter
Ma mentre è una singola proprietà, ci sono due sezioni separate di codice di applicazione l'impostazione ottenere e, ed è chiaro che si tratta di un getter / setter e non una velocità funzione, perché omettono il () per le proprietà . Così car.speed () è chiaramente una funzione, e car.speed è chiaramente un getter proprietà.
Altri suggerimenti
IMHO il C # stile di avere proprietà come zucchero sintattico per metodi get e set è il più espressivo.
Io preferisco gli oggetti attivi che incapsulano operazioni piuttosto che getter e setter, in modo da ottenere un'oggetti semanticamente più ricchi.
Per esempio, anche se un ADT piuttosto che un oggetto di business, anche il vector
in C ++ ha funzioni coppia:
size_type capacity() const // how many elements space is reserved for in the vector
void reserve(size_type n) // ensure space is reserved for at least n elements
e
void push_back ( const T& ) // inserts an element at the end
size_type size () const // the number of elements in the vector
Se si guida una macchina, è possibile impostare l'acceleratore, frizione, freni e la selezione delle marce, ma non si imposta la velocità. È possibile leggere la velocità fuori il tachimetro. E 'relativamente raro voler sia un setter e un getter su un oggetto con un comportamento.
Cordiali saluti, Objective-C utilizza car.speed()
e car.setSpeed(55)
(tranne che in una sintassi diversa, [car speed]
e [car setSpeed:55]
.
E 'tutta una questione di convenzione.
Non c'è una risposta giusta, è una questione di stile, e, infine, non ha importanza. Trascorrete le vostre cicli cervello altrove.
FWIW preferisco il class.noun () per il getter, e class.verb () per il setter. A volte il verbo è solo setNoun (), ma altre volte no. Dipende dal sostantivo. Ad esempio:
my_vector.size()
restituisce la dimensione, e
my_vector.resize(some_size)
Modifica le dimensioni.
L'approccio groove alla proprietà è abbastanza eccellente IMHO, http://groovy.codehaus.org/Groovy + Fagioli
I parametri di riferimento finali del vostro codice dovrebbe essere questo:
- Funziona correttamente?
- E 'facile da risolvere se si rompe?
- E 'facile aggiungere nuove funzionalità in futuro?
- E 'facile per qualcun altro per entrare e risolvere / valorizzarlo?
Se quei 4 punti sono coperti, non posso immaginare perché qualcuno dovrebbe avere un problema con esso. La maggior parte delle "Best Practices" sono generalmente orientati verso il raggiungimento di quei 4 punti.
Usa quello stile funziona per voi, basta essere coerenti su di esso, e si dovrebbe andare bene.
Questa è solo una questione di convenzione. In Smalltalk, è fatto il modo in cui si suggeriscono e non ricordo di aver mai sentito nessuno lamentarsi. Ottenere la velocità della vettura è car speed
, e impostando la velocità della vettura a 55 è car speed:55
.
Se dovessi azzardare un'ipotesi, direi che il motivo per cui questo stile non ha interferito sopra è a causa delle due linee lungo il quale la programmazione orientata agli oggetti sono venuti a noi: C ++ e Objective-C. In C ++ (ancora di più all'inizio della sua storia), i metodi sono strettamente correlate a funzioni C, e funzioni C sono convenzionalmente chiamato lungo le linee di setWhatever()
e non hanno un sovraccarico per un diverso numero di argomenti, in modo che lo stile generale della denominazione è stata tenuto. Objective-C è stato in gran parte preservata da NeXT (che in seguito divenne Apple), e accanto tendeva a favorire la verbosità nei loro API e soprattutto di distinguere tra diversi tipi di metodi - se si sta facendo nulla, ma solo accesso a una proprietà, NeXT ha voluto un verbo per mettere in chiaro. In modo che è diventato la convenzione in Cocoa, che è la libreria standard de facto per Objective-C in questi giorni.
E 'convenzione Java ha una convenzione di getter e setter C # è proprietà, Python ha i campi pubblici e framework JavaScript tendono ad usare campo () per ottenere e il campo (valore) per impostare
A parte la chiarezza inequivocabile, perché dovremmo attenerci a:car.getSpeed() e car.setSpeed(55) quando questo potrebbe essere usato pure:auto.velocità() e auto.velocità(55)
Perché in tutte le lingue che ho incontrato, car.speed()
E car.speed(55)
sono gli stessi in termini di sintassi.Guardandoli così, entrambi potrebbero restituire un valore, il che non è vero per quest'ultimo se dovesse essere un palleggiatore.
Che cosa succede se si ha intenzione di chiamare il setter ma dimentica di mettere in discussione? Il codice è valido, in modo che il compilatore non si lamenta, e non genera un errore di runtime immediata; si tratta di un bug in silenzio.
. () Significa che è un verbo. no () significa che è un sostantivo.
car.Speed = 50;
x = car.Speed
car.Speed.set(30)
car.setProperty("Speed",30)
ma
car.Speed()
implica comando per superare il limite di velocità.