Performance vs. Pigrizia: perché usare setter all'interno di una classe?

2

Ho notato che il codice relativo al Web utilizza i metodi setter per impostare i campi di classe invece di impostarli direttamente poiché sono nell'ambito. Trovo che sia un po 'strano. L'uso dei setter è sicuramente più sicuro, ma se vengono implementati i test unitari, si troveranno dei bug. E non vale la chiamata extra stack, imo.

Qualche codice di produzione fa questo o è solo ciò che vedi nel codice di esempio online?

Modifica: Devo chiarire che sto parlando solo del caso in cui il setter consiste esclusivamente di una singola espressione di assegnazione e nient'altro.

    
posta Tom Jones 26.08.2011 - 04:51
fonte

6 risposte

5

Devi seguire il principio aperto / chiuso . Non usare il setter significa che la tua classe non è aperta all'estensione, perché le sottoclassi che sovrascrivono il setter per mantenere la coerenza interna aggiungendo una logica diversa all'interno della chiamata non avranno quella logica eseguita e quindi finiranno con uno stato incoerente.

Al contrario, l'argomento con la chiamata extra è praticamente nullo.
O il setter è sovrascritto in una sottoclasse, il che significa che non usarlo non è strettamente un'opzione. O il setter non è sovrascritto, nel qual caso qualsiasi ottimizzatore (JIT) decente sarà in grado di inline e ottenere così le stesse prestazioni.

    
risposta data 26.08.2011 - 11:50
fonte
11

Mai e poi mai dipendere dai test delle unità quando non puoi dipendere da loro. Safety 101: Garantirlo in fase di compilazione invece di sperare, testare o controllarlo in fase di esecuzione. Se hai un setter per una variabile, è per una buona ragione, e non dovresti aggirarla senza una ragione ancora migliore.

    
risposta data 26.08.2011 - 04:59
fonte
5

Per quanto riguarda le prestazioni, un moderno compilatore di Just In Time invierà In-Line alla chiamata setter se è veramente solo un set banale. Non c'è alcuna assegnazione di un nuovo stack di metodi o di qualsiasi costo da prendere in considerazione. Evitare l'uso di getter / setter non è in realtà un problema di prestazioni anche se si tratta di una micro-ottimizzazione. (sì, c'è un costo per eseguire la linea, ma la domanda si riferisce alle webapp, dove apparentemente ciò accade una volta e il server rimane attivo indefinitamente.)

Quindi alcune cose a favore dell'uso dei setter

1) Il setter potrebbe non essere un semplice set per tutti i tempi. Immagino che questa sia un'opinione personale, ma sperando che i test automatici catturino tutti i bug eventualmente introdotti saltando un setter che in seguito ottiene effetti collaterali sembra ingenuo.

2) I metodi Set possono essere strumentati in fase di esecuzione da altri framework. I sistemi di persistenza e i framework di programmazione orientati all'aspetto possono entrambi aggiungere funzionalità aggiuntive per impostare metodi che non si vedono nell'origine della classe. E ancora, solo perché uno non è in uso ora, non significa che non lo sarà mai.

3) Un campo a cui si accede tramite un metodo set è chiaramente visibile esternamente e lo stato modificabile, in contrapposizione a un campo veramente privato senza accessors che è chiaramente stato interno. Può migliorare la comprensione se i campi che rappresentano solo lo stato gestito internamente "risaltano" nel codice per mancanza di chiamate impostate.

4) Meno preoccupazioni su bug in cui le persone lasciano il "questo". e impostare una variabile per l'ambito del metodo anziché la variabile dell'ambito dell'istanza che hanno nascosto in modo sleale. (È incredibile quante persone si sono condizionate a ignorare completamente gli avvisi del compilatore, anche negli IDE che li evidenziano.)

A favore di non usare il setter

1) Tutto quello che posso inventare è che alcune persone potrebbero trovare più facile da leggere.

    
risposta data 26.08.2011 - 09:53
fonte
3

Gran parte di essa risale al libro di Bertrand Meyer e al suo Principio di accesso uniforme, oppure allo standard Bean.

Se non stiamo filtrando o massaggiando i dati nei nostri getter / setter, non vedo molti punti nello scrivere metodi getter / setter. Se hai 'int getX ()' e cambi l'implementazione per raddoppiare, ti baserai comunque sul compilatore per trovare i posti da cambiare. Allo stesso modo, se vuoi aggiungere una modifica a un vecchio membro pubblico.

La maggior parte delle persone segue la regola pedissequamente. Perché non provi a romperlo qualche volta e a vedere cosa ti insegna? Pensa a quali situazioni giustificano un involucro aggiuntivo e quando è uno sforzo inutile. Mantenere le note

    
risposta data 26.08.2011 - 05:26
fonte
2

Nel codice orientato agli oggetti, in cui i setter / getter delle classi figlie possono essere diversi, dovresti sempre usarli.

    
risposta data 26.08.2011 - 09:15
fonte
2

ciò che costituisce un valore valido e l'implementazione dell'accompagnatore cambia più spesso di quanto dovresti gestire manualmente.

è altamente noioso e soggetto a errori per verificare che tutti gli accessi diretti seguano i requisiti impostati dal setter quando cambiano le implementazioni. a quel punto, ti rendi conto che stai convalidando e copiando il codice in tutto quel luogo (beh, ci sono molti programmatori che si fidano solo di non introdurre un bug), il che peggiora solo il problema dando più implementazioni per convalidare manualmente e più possibilità di errore. man mano che il programma si evolve, è più facile e più semplice usare sempre il setter e andare avanti con la vita.

in alcuni casi, avrai bisogno di un accesso diretto. questo varia in base alla lingua, ma è comune durante l'inizializzazione e la distruzione.

per quanto riguarda le prestazioni: se il costo delle chiamate di funzione è un problema di prestazioni valido , potresti utilizzare strumenti, linguaggio o approccio errati. faccio molto lavoro in c ++ - il costo è banale a nulla nelle build ottimizzate se ben scritto. altre lingue non sono così buone al riguardo.

    
risposta data 26.08.2011 - 11:16
fonte

Leggi altre domande sui tag