Mon entreprise vient de me demander de réécrire une application Java de grande taille (50 000 lignes de code) (une application Web utilisant JSP et servlets) dans Clojure. Quelqu'un d'autre a-t-il des conseils sur ce à quoi je dois faire attention?
Veuillez garder à l'esprit que je connais assez bien Java ET Clojure.
Mettre à jour
J'ai fait la réécriture et elle est entrée en production. C'est assez étrange car la réécriture a fini par aller si vite qu'elle a été faite en environ 6 semaines. Parce que beaucoup de fonctionnalités n'étaient pas encore nécessaires, cela ressemblait plus à 3000 lignes de Clojure.
J'entends qu'ils sont satisfaits du système et qu'il fait exactement ce qu'ils voulaient. Le seul inconvénient est que le gars qui entretient le système a dû apprendre Clojure à partir de zéro, et il a été entraîné à coups de pied et de cris. J'ai reçu un appel de lui l'autre jour en disant qu'il aimait Lisp maintenant ... drôle :)
Aussi, je devrais mentionner Vaadin. Utiliser Vaadin représentait probablement autant de gain de temps et de brièveté du code que Clojure. Vaadin est toujours le meilleur framework Web que j'ai jamais utilisé, même si maintenant j'apprends ClojureScript dans la colère! (Notez que Vaadin et ClojureScript utilisent tous deux les frameworks d'interface graphique de Google sous le capot.)
Réponses:
Le plus gros "problème de traduction" sera probablement de passer d'une méthodologie Java / POO à un paradigme de programmation Clojure / fonctionnel.
En particulier, au lieu d'avoir un état mutable dans les objets, la "méthode Clojure" consiste à séparer clairement l'état mutable et à développer des fonctions pures (sans effet secondaire). Vous savez probablement déjà tout cela :-)
Quoi qu'il en soit, cette philosophie a tendance à conduire vers un style de développement «ascendant» où vous concentrez les efforts initiaux sur la construction du bon ensemble d'outils pour résoudre votre problème, puis les branchez ensemble à la fin. Cela pourrait ressembler à quelque chose comme ça
Identifiez les structures de données clés et transformez-les en définitions immuables de carte ou d'enregistrement Clojure. N'ayez pas peur d'imbriquer de nombreuses cartes immuables - elles sont très efficaces grâce aux structures de données persistantes de Clojure. Cela vaut la peine de regarder cette vidéo pour en savoir plus.
Développez de petites bibliothèques de fonctions pures orientées vers la logique métier qui opèrent sur ces structures immuables (par exemple «ajouter un article au panier»). Vous n'avez pas besoin de faire tout cela en même temps car il est facile d'en ajouter plus tard, mais cela aide à en faire quelques-uns tôt pour faciliter les tests et prouver que vos structures de données fonctionnent ... point que vous pouvez réellement commencer à écrire des éléments utiles de manière interactive à la REPL
Développez séparément des routines d'accès aux données qui peuvent conserver ces structures vers / depuis la base de données ou le réseau ou le code Java hérité selon les besoins. La raison de garder cela très distinct est que vous ne voulez pas que la logique de persistance soit liée à vos fonctions de «logique métier». Vous voudrez peut-être consulter ClojureQL pour cela, bien qu'il soit également assez facile d'encapsuler tout code de persistance Java que vous aimez.
Écrivez des tests unitaires (par exemple avec clojure.test ) qui couvrent tout ce qui précède. Ceci est particulièrement important dans un langage dynamique comme Clojure car a) vous n'avez pas autant de filet de sécurité contre la vérification de type statique et b) cela aide à être sûr que vos constructions de niveau inférieur fonctionnent bien avant de trop construire sur en haut d'eux
Décidez de la manière dont vous souhaitez utiliser les types de référence de Clojure (vars, refs, agents et atomes) pour gérer l'état de chaque partie mutable au niveau de l'application. Ils fonctionnent tous de la même manière mais ont une sémantique transactionnelle / simultanée différente en fonction de ce que vous essayez de faire. Les références seront probablement votre choix par défaut - elles vous permettent d'implémenter un comportement transactionnel STM "normal" en enveloppant n'importe quel code dans un bloc (dosync ...).
Sélectionnez le bon framework web global - Clojure en a déjà quelques-uns, mais je recommande fortement Ring - regardez cette excellente vidéo " One Ring To Bind Them " plus Fleet ou Enlive ou Hiccup en fonction de votre philosophie de création de modèles. Ensuite, utilisez ceci pour écrire votre couche de présentation (avec des fonctions telles que "traduire ce panier en un fragment HTML approprié")
Enfin, écrivez votre application en utilisant les outils ci-dessus. Si vous avez correctement suivi les étapes ci-dessus, ce sera en fait la solution la plus simple, car vous serez en mesure de créer l'ensemble de l'application par une composition appropriée des différents composants avec très peu de passe-partout.
C'est à peu près la séquence dans laquelle j'attaquerais le problème car il représente globalement l'ordre des dépendances dans votre code et convient donc à un effort de développement "ascendant". Bien sûr, dans un bon style agile / itératif, vous vous retrouverez probablement à pousser tôt vers un produit final démontrable, puis à revenir assez fréquemment aux étapes précédentes pour étendre la fonctionnalité ou le refactoriser au besoin.
ps Si vous suivez l'approche ci-dessus, je serais fasciné d'entendre combien de lignes de Clojure il faut pour correspondre à la fonctionnalité de 50000 lignes de Java
Mise à jour : depuis la rédaction de cet article, quelques outils / bibliothèques supplémentaires sont apparus dans la catégorie "à vérifier":
la source
Quels aspects de Java votre projet actuel inclut-il? Journalisation, transactions de base de données, transactions déclaratives / EJB, couche Web (vous avez mentionné JSP, servlets) etc. J'ai remarqué que l'éco-système Clojure a divers micro-frameworks et bibliothèques dans le but de faire une tâche et de bien le faire. Je suggérerais d'évaluer les bibliothèques en fonction de vos besoins (et si cela pourrait être mis à l'échelle dans de grands projets) et de prendre une décision éclairée. (Clause de non-responsabilité: je suis l'auteur de bitumenframework ) Une autre chose à noter est le processus de construction - si vous avez besoin d'une configuration complexe (développement, test, mise en scène, production), vous devrez peut-être diviser le projet en modules et avoir le processus de construction scripté pour facilité.
la source
J'ai trouvé que la partie la plus difficile était de penser à la base de données. Faites quelques tests pour trouver les bons outils que vous souhaitez utiliser.
la source