2009-12-01 22 views
31

Tengo el hábito de utilizar Cierres en todas partes que puedo en lugar de métodos regulares, incluso cuando no necesito acceso a variables gratuitas. Por lo tanto, voy a utilizar esto:Groovy: Cierres o Métodos

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

.. en lugar de esto:

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

¿Es esta mala práctica? Prefiero mucho más poder que obtengo cuando uso cierres sobre métodos, y prefiero la sintaxis.

Gracias!

+3

Solo recuerde que no puede especificar fácilmente el tipo de devolución del cierre. Para los métodos es mucho más fácil. Además, los cierres no funcionan bien con '@ TypeChecked' o' @ CompileStatic'. – Seagull

Respuesta

40

Solo uso cierres donde los necesito, es decir, uso métodos por defecto. Lo hago porque

  • métodos son más simples que los cierres. Los cierres tienen un delegado, un propietario, retienen el acceso a las variables que estaban en su ámbito local cuando se crean (lo que usted llama "variables libres"). Por método predeterminado llama dentro de un cierre que se resuelvan por:

    1. propio cierre
    2. propietario Cierre
    3. Cierre delegado

Pero este orden se puede cambiar en tiempo de ejecución, y un cierre de delegado también se puede cambiar a cualquier objeto.

Todos estos factores combinados pueden hacer algo de código que utiliza cierres muy difícil de asimilar, por lo que si usted no necesita cualquiera de esta complejidad prefiero eliminarla mediante un método en lugar

  • Un El archivo .class se genera para cada cierre definido en Groovy. Tengo exactamente cero pruebas para respaldar una afirmación de que un método regular es más eficaz que un cierre, pero tengo sospechas. Por lo menos, una gran cantidad de clases puede hacer que se quede sin espacio de memoria PermGen - esto se utiliza para pasar a mí con frecuencia hasta que alcé mi espacio PermGen a alrededor de 200 MB

no tengo ni idea de si la práctica I Estoy defendiendo (usar métodos por defecto y cierres solo cuando los necesita) es ampliamente considerado como una "mejor práctica", por lo que tengo curiosidad por escuchar lo que otros piensan.

6

Si bien todas las cosas que dice @Don son ciertas, no sé si alguna de ellas es tan significativa. Puede anular al delegado de un cierre que puede cambiar la ejecución, pero a menos que esté pasando el cierre (lo cual no se puede hacer con un método de todos modos), realmente no tiene que preocuparse por ninguna de esas cosas. Jugar con el delegado es una característica, no una responsabilidad.

En cuanto a un posible impacto en el rendimiento de los archivos de clase adicionales, ¿por qué estás usando Groovy si estás preocupado por el rendimiento?

Mi opinión es que en realidad no importa. Si tiene mucha gente en su equipo que son desarrolladores antiguos de Java, probablemente le desagraden cuando usa cierres en los que un método funcionará.Por otro lado, alguien con fluidez en Groovy se molestará si desordena todo con métodos cuando un cierre tiene más sentido.

tl; dr - No hay una regla rígida y rápida, en su lugar debe ejercer su buen juicio con miras a la legibilidad del código.

+1

Estoy totalmente de acuerdo en que mis puntos son relativamente menores, y la concisión es una consideración mucho más importante. –

+1

Dependiendo del uso, el uso excesivo de cierres puede provocar un mayor rendimiento y la degradación de la memoria, debido a las instancias 'java.lang.ref.SoftReference' posiblemente no liberadas. En las secuencias de comandos y las clases normales, eso no será un problema, pero en algunos casos particulares (por ejemplo, grandes XML para tratar con 'MarkupBuilder') debe evitar el uso de cierres. –

+1

Generalmente prefiero el buen estilo a la optimización prematura. Siempre es una buena idea crear un perfil de tu código de vez en cuando, y eso te ayudaría a identificar oportunidades para optimizar. Por supuesto, cada nueva versión de Groovy (y JDK del mismo modo) podría traer un nuevo conjunto de optimizaciones, por lo que la optimización de su código debe hacerse sobre una base de costo/beneficio. En pocas palabras: escriba el código más legible e intuitivo que pueda y no pierda el tiempo optimizando algo que probablemente se optimizará para usted. – ngreen