2009-12-01 2 views
31

Ho preso l'abitudine di utilizzare Closures ovunque possibile al posto di metodi regolari, anche quando non ho bisogno di accedere a variabili libere. Così, userò questo:Groovy: chiusure o metodi

def addNumbers = { left, right -> left + right }

.. invece di questo:

def addNumbers (left,right) { left + right }

È questa cattiva pratica? Preferisco di gran lunga la potenza extra che ottengo quando uso le chiusure sui metodi, e preferisco di gran lunga la sintassi.

Grazie!

+3

Basta ricordare che non è possibile specificare facilmente il tipo di chiusura di chiusura. Per i metodi è molto più facile. Inoltre, le chiusure non funzionano bene con '@ TypeChecked' o' @ CompileStatic'. – Seagull

risposta

40

Io uso solo chiusure dove ho bisogno di esse, ad esempio utilizzo i metodi di default. Lo faccio perché

  • I metodi sono più semplici di chiusure. Le chiusure hanno un delegato, un proprietario, mantenere l'accesso alle variabili che erano nel loro ambito locale una volta create (quelle che chiamate "variabili libere"). Con metodo predefinito chiama all'interno di una chiusura vengono risolti da:

    1. Chiusura stesso
    2. proprietario Chiusura
    3. Chiusura delegato

Ma questo ordine può essere modificato in fase di esecuzione, e una chiusura di delegato può anche essere cambiato in qualsiasi oggetto.

Tutti questi fattori combinati può fare un po 'di codice che utilizza le chiusure molto difficile da Grok, quindi se non è necessario alcun di questa complessità preferisco eliminarlo utilizzando un metodo invece

  • A Il file .class viene generato per ogni chiusura definita in Groovy. Ho esattamente zero prove per sostenere che un metodo regolare è più performante di una chiusura, ma ho dei sospetti. Per lo meno, un sacco di classi possono farti esaurire lo spazio di memoria PermGen - questo mi accadeva frequentemente fino a quando ho aumentato il mio spazio PermGen a circa 200MB

Non ho idea se la pratica I sto sostenendo (uso i metodi di default e chiusure solo quando ne hai bisogno) è ampiamente considerato una "migliore pratica", quindi sono curioso di sentire cosa pensano gli altri.

6

Mentre tutte le cose che @Don dice sono vere, non so se nessuna di esse sia così significativa. Puoi ignorare il delegato di una chiusura che può cambiare l'esecuzione, ma a meno che non passi la chiusura (cosa che comunque non puoi fare con un metodo) non devi preoccuparti di nessuna di queste cose. Giocare con il delegato è una caratteristica, non una responsabilità.

Per quanto riguarda un possibile riscontro di prestazioni da file di classe extra, perché stai utilizzando Groovy se sei preoccupato per le prestazioni?

La mia opinione è che non ha molta importanza. Se nella tua squadra ci sono molte persone che sono vecchi sviluppatori Java, probabilmente non ti piaceranno quando utilizzerai chiusure dove un metodo funzionerà.D'altra parte, qualcuno che parla fluentemente di Groovy si arrabbierà se si riempie tutto con i metodi quando una chiusura ha più senso.

tl; dr - Non esiste una regola dura e veloce, invece è necessario esercitare un buon giudizio con un occhio alla leggibilità del codice.

+1

Sono assolutamente d'accordo sul fatto che i miei punti sono relativamente minori, e la concisione è una considerazione molto più importante. –

+1

A seconda dell'utilizzo, l'uso eccessivo delle chiusure potrebbe comportare un peggioramento delle prestazioni e della memoria, a causa di possibili istanze 'java.lang.ref.SoftReference' non pubblicate. Negli script e nelle classi regolari ciò non costituirà un problema, ma in alcuni casi particolari (ad esempio, enormi XML per trattare con 'MarkupBuilder') si dovrebbe evitare l'uso di chiusure. –

+1

Preferisco generalmente un buon stile rispetto all'ottimizzazione prematura. È sempre una buona idea profilare il tuo codice di volta in volta e ciò ti aiuterà a identificare le opportunità da ottimizzare. Naturalmente, ogni nuova versione di Groovy (e JDK allo stesso modo) potrebbe portare a una nuova serie di ottimizzazioni, pertanto l'ottimizzazione del codice dovrebbe essere effettuata a costi/benefici. In conclusione: scrivi il codice più leggibile e intuitivo che puoi e non perdere tempo a ottimizzare qualcosa che sarà probabilmente ottimizzato per te. – ngreen