java groovy dynamic-languages paradigms

java - ¿Puedes tener demasiado "dinámico" en idiomas dinámicos?



groovy dynamic-languages (6)

En los últimos meses he estado haciendo una transición de Java a Groovy y puedo apreciar muchos de los beneficios que trae: menos código, cierres, constructores, MOP que al final hace posible el uso de frameworks como Grails, facilidad con la burla al escribir pruebas, etc. .

Sin embargo, mis compañeros de trabajo me han "acusado" de que mi código no es lo suficientemente maravilloso. Es decir, sigo declarando tipos para mis parámetros y campos, uso herencia y polimorfismo en lugar de tipado de pato, etc. Me parece que en estas situaciones no solo es dinámico vs. estático, sino también dinámico frente a paradigma orientado a objetos tipo de dilema En esos casos, todavía tiendo a preferir OO. Siento que el paradigma OO tiene un gran valor en su premisa básica al permitirle abstraer y relacionar las construcciones de su código con conceptos particulares del mundo real.

Entonces, aquí hay preguntas particulares con las que necesito ayuda:

  1. ¿Debo declarar tipos para mis parámetros, campos, etc.?

  2. ¿Debería declarar el bloqueo de código como cierre cuando lo haga un método simple?

  3. ¿Cuándo debo usar el tipado de pato en lugar del envío dinámico polimórfico? Por ejemplo, en groovy puedo hacer animal. "$ Action" () o def animal; animal.action (), en lugar de Animal animal = new Dog (); animal.action (). Puedo ver el problema primero en el contexto del principio de Open-Closed, pero ¿hay alguna otra razón para preferir el polimorfismo de OO?

  4. ¿Cuándo debería usar interfaces en Groovy (si alguna vez)?

Estoy seguro de que existen otros dilemas similares que no pude escribir. También creo que estas preguntas son válidas no solo para groovy, sino para cualquier otro lenguaje dinámico. ¿Cuál es tu opinión?


Esta no es siempre una opinión popular, pero creo que cuanto más explícito y claro sea su código, mejor.

No me gustan los constructos que te dejan adivinar lo que está pasando ...

Trabajé durante un año en Ruby y no me gustó para nada. No digo que no tenga lugares en los que sobresalga, solo digo que realmente me gusta mantener las cosas limpias y explícitas, y no sentía que Ruby tuviera ese objetivo.

Una cosa que sí descubrí es segura: la cantidad de tipeo que haces no equivale a la velocidad de desarrollo general. Es cierto que una base de código complicada con muchos códigos repetidos hace que el desarrollo sea muy lento, pero simplemente reducir lo que escribe sin eliminar la duplicación es inútil, y escribir un código más largo, más claro y más explícito generalmente será más rápido (sobre el duración del proyecto) que el mismo código escrito en un lenguaje escueto y menos formal.

Si no cree que la mecanografía no tiene relación con la velocidad de desarrollo, la próxima vez que lance un proyecto cuente el número de líneas de código y divida por los días-hombre pasados ​​(incluida la depuración y las pruebas). En otras palabras, cuánto código se tipeó al día. Encontrará que el resultado es un número muy pequeño: en realidad, escribir código es una parte muy pequeña de cualquier proyecto de software.


Hay dos tipos dominantes de lenguajes orientados a objetos.

Los idiomas de la familia Simula 67 , como C ++ y Java, favorecen las variables con tipado estático, los compiladores y vinculadores, y los métodos vtables.

Los lenguajes de la familia Smalltalk , como Ruby, favorecen las variables de tipo dinámico, la interpretación y la transmisión de mensajes en lugar de las tablas de punteros a la función.

Ambos están orientados a objetos, pero muy diferentes adoptan el concepto de orientación a objetos.


-

NO

¿Te das cuenta de que no hay una respuesta real para esta pregunta?


Todo se reduce a lo que las personas se sienten cómodas. Me gusta usar declinaciones de tipo y llamadas a métodos porque me siento cómodo con Java. El código que escribo debe ser mantenido por personas sin mucha experiencia en programación dinámica, así que lo mantendré cerca del código Java normal a menos que haya una buena razón para usar una función avanzada de groovy. Parece que su grupo debe crear estándares de codificación que intenten explicar cuándo se deben usar las características específicas de Groovy.


.1. ¿Debo declarar tipos para mis parámetros, campos, etc.?

Tiendo a declarar tipos en clases que se usan como parte de una API pública, cosas que otros desarrolladores consumirán mucho, o donde me gustaría un poco de ayuda de autocompletar adicional de IntelliJ. De lo contrario, ''def'' las cosas.

.2. ¿Debería declarar el bloqueo de código como cierre cuando lo haga un método simple?

Uso métodos a menos que sea algo que planeo pasar como una variable. Aunque existe el operador de eliminación de referencias del método "foo. & Bar", la mayoría de los desarrolladores no lo conocen y se sienten confundidos cuando se topan con él. También utilizo cierres cuando es un pequeño fragmento de código que es claro para permanecer en un método más grande en lugar de ponerlo en su propio método con fines descriptivos.

.3. ¿Cuándo debo usar el tipado de pato en lugar del envío dinámico polimórfico? Por ejemplo, en groovy puedo hacer animal. "$ Action" () o def animal; animal.action (), en lugar de Animal animal = new Dog (); animal.action (). Puedo ver el problema primero en el contexto del principio de Open-Closed, pero ¿hay alguna otra razón para preferir el polimorfismo de OO?

Solo uso el formulario animal "$ action" () cuando necesito ese nivel de direccionamiento indirecto porque el nombre del método varía en función de la ruta de ejecución del código (más a menudo durante la metaprogramación pesada). Yo uso animal animal = nuevo perro (); animal.action () cuando quiero la ayuda del IDE con el autocompletado, o ese nivel de documentación es útil para la claridad del código (y no me afecta la verbosidad adicional que puede ser obvia o restrictiva).

.4. ¿Cuándo debería usar interfaces en Groovy (si alguna vez)?

Raramente los uso. Podría verlos usándolos principalmente como documentación de los campos esperados para una llamada API pública, o posiblemente como una interfaz de marcador para ayudar a distinguir un conjunto de clases de otro desde una perspectiva de metaprogramación. Son mucho menos útiles en Groovy que en Java.


Creo que con Groovy deberías favorecer la forma más simple de hacer algo, y recurrir a las características groovier solo cuando la situación lo requiera. (Como cuando se escriben macros o se crean métodos multimétodos en Clojure, si se encuentra buscando esas herramientas mucho, debería cuestionarse). Su enfoque prudente me parece bien, posiblemente sus compañeros de trabajo estén un poco intoxicados con su poder recién descubierto. . (No sería la primera vez)

Lo bueno de tener un lenguaje flexible como Groovy es que puedes comenzar con un enfoque prudente como si prefirieras saber que tienes alternativas más poderosas para recurrir cuando las necesites. Ya sabes, "lo más simple que podría funcionar".

Más específicamente, prefiriendo el tipado de patos sobre las interfaces y no molestarse con los tipos de parámetros parece que podría ser algo bueno, puede facilitar mucho el suministro de simulacros a las pruebas.