refactoring clojure

refactoring - Técnicas de refactorización para clojure.



(3)

Estoy familiarizado con la refactorización de bases de código bastante grandes en C # y Java, pero Clojure es una especie de bestia diferente, especialmente porque:

  • ¿Tiene una mezcla de macros y funciones en el código típico (es decir, es posible que desee refactorizar de una macro a una función o viceversa?)
  • Utiliza la escritura dinámica en la mayoría de las circunstancias (por lo que no obtiene controles de tiempo de compilación sobre la corrección de su código refactorizado)
  • Es funcional más que orientado a objetos en estilo
  • Tiene menos soporte para refactorización en IDE actuales.
  • Es menos tolerante con las dependencias cíclicas en las bases de código (¡esto hace que sea más difícil mover bloques de código / definiciones!)

Dado lo anterior, ¿cuál es la mejor manera de abordar la refactorización de código en Clojure?


En "Trabajar de manera efectiva con el código heredado", Michael Feathers sugiere agregar pruebas unitarias para crear "puntos de inflexión" artificiales en el código con el que se puede modificar el factor.

un resumen súper breve y completamente incompleto sobre su enfoque para agregar orden al código no estructurado:

  • Dividir el código en "Legacy" (sin pruebas) y el resto.
  • crear una prueba
  • repetir en ambas mitades.

El enfoque recursivo pareció encajar bien con los procesos mentales que uso al pensar en Clojure, por lo que he llegado a asociarlos. Incluso los nuevos idiomas pueden tener código legado ¿verdad?

Esto es lo que obtuve de mi lectura de ese libro mientras pensaba en el clojure. Así que espero que sea de utilidad como guía general. Tal vez su base de código ya tenga buenas pruebas, en cuyo caso ya está más allá de esta fase.


No estoy familiarizado con la refactorización de bases de código bastante grandes en C # o Java, pero aquí va.

Clojure:

  • Tiene una mezcla de macros y funciones : podría estar equivocado, pero creo que encontrará que la refactorización rara vez mueve la interfaz entre macros y funciones.

  • Utiliza la escritura dinámica (para que no obtengas controles de tiempo de compilación en el código refactorizado) : ... ni en ningún otro código: necesitas más pruebas en ambos casos.

  • Es funcional en lugar de orientado a objetos en estilo Las refactorizaciones se expresan en términos OO, pero a menudo sobreviven a la transcripción simple: método a función, clase a función o cierre o mapa.

  • Tiene menos soporte para refactorización en IDEs actuales. Verdadero: trabajo más ocupado.

  • Es menos tolerante con las dependencias cíclicas en las bases de código Dos casos: la recursión mutua en un espacio de nombres / archivo debería ser más fácil de manejar de lo que es; pero las dependencias cíclicas entre espacios de nombres / paquetes causan confusión y ambigüedad. Creo que Java solo les permitió porque C ++ lo hizo, y C # siguió su ejemplo.

Me ha resultado útil consultar el catálogo de refactorizaciones de Martin Fowler. La mayoría sobrevive de la traducción de OO a la jerga funcional. Algunos (como Cambiar el valor de referencia ) desaparecen.


No soy un experto. Pero de todos modos:

  • Manténgase alejado de las funciones de God . Si tiene una función grande, divídala en funciones más pequeñas y cada una de estas funciones está haciendo una cosa, y la está haciendo bien.
  • Si encuentra uso de arreglos Java (y no es necesario usarlos), conviértalos a secuencias de Clojure.
  • Abrazar defrecord y defprotocol .
  • Manténgase alejado de las macros a menos que realmente no pueda continuar sin escribir una macro.
  • Cuando sea posible, favorece las secuencias perezosas sobre la recursividad.
  • Al crear un servicio, coloque el contrato en su propio espacio de nombres y la implementación en su propio espacio de nombres.
  • Lograr la inyección de dependencias como funciones de paso como parámetros a otras funciones.
  • Use la desestructuración para el arglista de una función cuando sea posible. Esto llevará a una implementación de una función más fácil de entender.
  • Considere la posibilidad de utilizar el proyecto de esquema prismático.

Además, echa un vistazo a CursiveClojure. Creo que es realmente prometedor.

No soy el creador de CursiveClojure.