Mi empresa me acaba de pedir que reescriba una aplicación Java grande (50.000 líneas únicas de código) (una aplicación web que usa JSP y servlets) en Clojure. ¿Alguien más ha recibido consejos sobre lo que debo tener en cuenta?
Tenga en cuenta que conozco bastante bien tanto Java como Clojure.
Actualizar
Hice la reescritura y entró en producción. Es bastante extraño ya que la reescritura terminó yendo tan rápido que se hizo en aproximadamente 6 semanas. Debido a que todavía no se necesitaba mucha funcionalidad, terminó más como 3000 líneas de Clojure.
Escuché que están contentos con el sistema y está haciendo exactamente lo que querían. El único inconveniente es que el tipo que mantenía el sistema tuvo que aprender Clojure desde cero, y fue arrastrado a él pateando y gritando. Recibí una llamada de él el otro día diciendo que ahora amaba a Lisp ... gracioso :)
Además, debería dar una buena mención a Vaadin. El uso de Vaadin probablemente representó la mayor parte del tiempo ahorrado y la brevedad del código como lo hizo Clojure. Vaadin sigue siendo el marco web superior que he usado, ¡aunque ahora estoy aprendiendo ClojureScript con ira! (Tenga en cuenta que tanto Vaadin como ClojureScript usan los marcos de GUI de Google debajo del capó).
Respuestas:
El mayor "problema de traducción" probablemente será pasar de una metodología Java / OOP a un paradigma de programación funcional / Clojure.
En particular, en lugar de tener un estado mutable dentro de los objetos, la "forma de Clojure" es separar claramente el estado mutable y desarrollar funciones puras (libres de efectos secundarios). Probablemente ya sepas todo esto :-)
De todos modos, esta filosofía tiende a conducir hacia una especie de estilo de desarrollo "de abajo hacia arriba" en el que concentra los esfuerzos iniciales en crear el conjunto de herramientas adecuado para resolver su problema, y finalmente conectarlos al final. Esto podría verse algo como esto
Identifique estructuras de datos clave y transfórmelas en definiciones de registros o mapas Clojure inmutables. No tenga miedo de anidar muchos mapas inmutables: son muy eficientes gracias a las estructuras de datos persistentes de Clojure. Vale la pena ver este video para obtener más información.
Desarrolle pequeñas bibliotecas de funciones orientadas a la lógica empresarial pura que operen en estas estructuras inmutables (por ejemplo, "agregar un artículo al carrito de compras"). No necesita hacer todo esto a la vez, ya que es fácil agregar más más adelante, pero ayuda hacer algunos desde el principio para facilitar las pruebas y demostrar que sus estructuras de datos están funcionando ... de cualquier manera en esto. punto que realmente puede comenzar a escribir cosas útiles de forma interactiva en el REPL
Desarrolle por separado rutinas de acceso a datos que puedan conservar estas estructuras hacia / desde la base de datos o la red o el código Java heredado según sea necesario. La razón para mantener esto muy separado es que no desea que la lógica de persistencia esté ligada a sus funciones de "lógica empresarial". Es posible que desee mirar ClojureQL para esto, aunque también es bastante fácil envolver cualquier código de persistencia de Java que desee.
Escriba pruebas unitarias (por ejemplo, con clojure.test ) que cubran todo lo anterior. Esto es especialmente importante en un lenguaje dinámico como Clojure ya que a) no tiene tanta red de seguridad para la verificación de tipos estáticos yb) ayuda a asegurarse de que sus construcciones de nivel inferior estén funcionando bien antes de construir demasiado en encima de ellos
Decida cómo desea usar los tipos de referencia de Clojure (vars, refs, agentes y átomos) para administrar cada estado de nivel de aplicación mutable de parte. Todos funcionan de manera similar, pero tienen diferentes semánticas transaccionales / de concurrencia dependiendo de lo que intente hacer. Las referencias probablemente serán su elección predeterminada: le permiten implementar un comportamiento transaccional STM "normal" al envolver cualquier código en un bloque (dosync ...).
Seleccione el marco web general correcto: Clojure ya tiene bastantes, pero recomiendo encarecidamente Ring: vea este excelente video " One Ring To Bind Them " más Fleet o Enlive o Hiccup, dependiendo de su filosofía de creación de plantillas. Luego, use esto para escribir su capa de presentación (con funciones como "traducir este carrito de compras en un fragmento HTML apropiado")
Finalmente, escriba su aplicación usando las herramientas anteriores. Si ha realizado los pasos anteriores correctamente, entonces esta será la parte fácil porque podrá construir la aplicación completa mediante la composición adecuada de los diversos componentes con muy poco texto repetitivo.
Esta es aproximadamente la secuencia en la que atacaría el problema, ya que representa ampliamente el orden de las dependencias en su código y, por lo tanto, es adecuada para un esfuerzo de desarrollo "de abajo hacia arriba". Aunque, por supuesto, con un buen estilo ágil / iterativo, probablemente se encontrará avanzando desde el principio hacia un producto final demostrable y luego saltando a los pasos anteriores con bastante frecuencia para ampliar la funcionalidad o refactorizar según sea necesario.
ps Si sigue el enfoque anterior, me fascinaría escuchar cuántas líneas de Clojure se necesitan para igualar la funcionalidad de 50,000 líneas de Java
Actualización : desde que esta publicación se escribió originalmente, han surgido un par de herramientas / bibliotecas adicionales que se encuentran en la categoría "debe consultar":
fuente
¿Qué aspectos de Java incluye su proyecto actual? Registro, transacciones de base de datos, transacciones declarativas / EJB, capa web (mencionó JSP, servlets), etc. He notado que el ecosistema Clojure tiene varios micro-frameworks y bibliotecas con el objetivo de hacer una tarea y hacerlo bien. Sugeriría evaluar las bibliotecas en función de sus necesidades (y si se ampliarían en proyectos grandes) y tomar una decisión informada. (Descargo de responsabilidad: soy el autor de bitumenframework ) Otra cosa a tener en cuenta es el proceso de compilación: si necesita una configuración compleja (desarrollo, prueba, preparación, producción), es posible que deba dividir el proyecto en módulos y tener el proceso de compilación programado para facilitar.
fuente
Encontré que la parte más difícil fue pensar en la base de datos. Realice algunas pruebas para encontrar las herramientas adecuadas que desea utilizar allí.
fuente