Переписать Java на Clojure

Моя компания только что попросила меня переписать большое (50 000 строк кода) Java-приложение (веб-приложение, использующее JSP и сервлеты) на Clojure. Есть ли у кого-нибудь еще советы о том, чего мне следует остерегаться?

Имейте в виду, что я достаточно хорошо знаю как Java, так и Clojure.

Обновлять

Я переписал, и он пошел в производство. Это довольно странно, ведь переписывание закончилось так быстро, что было сделано примерно за 6 недель. Поскольку много функциональности не требовалось, в итоге получилось больше 3000 строк Clojure.

Я слышал, что они довольны системой и делают именно то, что они хотели. Единственным недостатком является то, что парню, обслуживающему систему, пришлось выучить Clojure с нуля, и он был втянут в нее, пиная и крича. На днях мне действительно позвонил он и сказал, что теперь он любит Lisp ... смешно :)

Кроме того, я должен упомянуть Ваадина. Использование Vaadin, вероятно, привело к экономии времени и краткости кода, как и Clojure. Vaadin по-прежнему остается лучшим веб-фреймворком, который я когда-либо использовал, хотя теперь я изучаю ClojureScript в гневе! (Обратите внимание, что и Vaadin, и ClojureScript используют фреймворки графического интерфейса Google под капотом.)


person yazz.com    schedule 08.03.2011    source источник
comment
Я хочу работать в вашей компании.   -  person mtyaka    schedule 08.03.2011
comment
Ну, некоторые оборонные компании в Европе начали использовать Clojure (я слышал). Но не могу вспомнить ни одного имени :)   -  person yazz.com    schedule 08.03.2011
comment
@Zubair: 50 000 Java LOC далеко не велико. Это очень маленький проект. У меня есть Java-проект от 250KLOC до 300KLOC, и он среднего размера ... В лучшем случае.   -  person SyntaxT3rr0r    schedule 09.03.2011
comment
@Zubair: кстати ... Как вы думаете, сколько строк будет в коде Clojure? Уменьшение размера на 75%?   -  person SyntaxT3rr0r    schedule 09.03.2011
comment
На самом деле я, возможно, совершил ошибку, упомянув размер кодовой базы, поскольку, честно говоря, уменьшение размера кода не является целью переписывания. Цель двоякая: 1) сделать кодовую базу более понятной и, следовательно, дешевле поддерживать код 2) Разрешить пользователям инструмента расширять продукт с помощью редактора Clojure в веб-браузере (с использованием eval и других динамических качеств Clojure, которые более дорогостоящие для сделать на Яве)   -  person yazz.com    schedule 10.03.2011
comment
300KLOC !!! Вау ... Как этот самолет вообще летает!   -  person yazz.com    schedule 10.03.2011
comment
Эй ... только что посмотрел этот старый вопрос и задумался, как продвигается переписывание?   -  person levand    schedule 01.08.2011
comment
Я обновил вопрос обновлением   -  person yazz.com    schedule 25.09.2011
comment
Проголосовали за это обновление. Довольно интересно и полезно видеть завершение подобных случаев.   -  person efaj    schedule 18.08.2013
comment
История настолько яркая, что почти читается как реклама Clojure. Пожалуйста, скажите, что это было реально :)   -  person Alex    schedule 20.12.2015
comment
Это было давно, примерно 4 года назад. Проект добавил ценности компании, но я знаю, что компания в целом не приняла Clojure и в основном использовала .Net. К сожалению, на большом предприятии выбор технологии не является бизнес-решением. Выбирают именно технику, которая не увольняет менеджера, если что-то пойдет не так.   -  person yazz.com    schedule 23.12.2015


Ответы (3)


Самая большая «проблема перевода», вероятно, будет связана с переходом от методологии Java / OOP к парадигме Clojure / функционального программирования.

В частности, вместо того, чтобы иметь изменяемое состояние внутри объектов, «способ Clojure» состоит в том, чтобы четко отделить изменяемое состояние и разработать чистые (без побочных эффектов) функции. Вы, наверное, все это уже знаете :-)

В любом случае, эта философия имеет тенденцию вести к чему-то вроде стиля разработки «снизу вверх», когда вы сосредотачиваете начальные усилия на создании правильного набора инструментов для решения вашей проблемы, а затем, наконец, соединяете их вместе в конце. Это может выглядеть примерно так

  1. Определите ключевые структуры данных и преобразуйте их в неизменяемые определения карты или записи Clojure. Не бойтесь вкладывать множество неизменяемых карт - они очень эффективны благодаря постоянным структурам данных Clojure. Чтобы узнать больше, стоит посмотреть это видео.

  2. Разработайте небольшие библиотеки функций, ориентированных на чистую бизнес-логику, которые работают с этими неизменяемыми структурами (например, «добавить товар в корзину»). Вам не нужно делать все это сразу, так как позже легко добавить больше, но это помогает сделать несколько на раннем этапе, чтобы облегчить тестирование и доказать, что ваши структуры данных работают ... в любом случае в этом момент, вы можете начать писать полезные вещи в интерактивном режиме в REPL

  3. Отдельно разработать процедуры доступа к данным, которые могут сохранять эти структуры в / из базы данных, сети или устаревшего кода Java по мере необходимости. Причина, по которой это нужно держать отдельно, заключается в том, что вы не хотите, чтобы логика сохраняемости была связана с вашими функциями «бизнес-логики». Возможно, вам стоит взглянуть на ClojureQL для этого, хотя также довольно легко обернуть любой код сохраняемости Java, который вы нравиться.

  4. Напишите модульные тесты (например, с помощью clojure.test), которые охватывают все вышеперечисленное. . Это особенно важно для динамического языка, такого как Clojure, поскольку а) у вас нет такой защиты от статической проверки типов и б) это помогает убедиться, что ваши конструкции нижнего уровня работают хорошо, прежде чем вы будете слишком много строить на наверху из них

  5. Решите, как вы хотите использовать ссылочные типы Clojure (переменные, ссылки, агенты и атомы) для управления каждой частью изменяемого состояния на уровне приложения. Все они работают одинаково, но имеют разную семантику транзакций / параллелизма в зависимости от того, что вы пытаетесь сделать. Ссылки, вероятно, будут вашим выбором по умолчанию - они позволяют реализовать «нормальное» транзакционное поведение STM, заключая любой код в блок (dosync ...).

  6. Выберите правильный общий веб-фреймворк - у Clojure уже есть немало, но я настоятельно рекомендую Ring - посмотрите это отличное видео "One Ring To Bind Them" плюс Fleet или Enlive или Hiccup в зависимости от вашей философии создания шаблонов. Затем используйте это, чтобы написать свой уровень презентации (с такими функциями, как «преобразовать эту корзину для покупок в соответствующий фрагмент HTML»)

  7. Наконец, напишите свое приложение, используя указанные выше инструменты. Если вы выполнили описанные выше шаги правильно, то это действительно будет легко, потому что вы сможете построить все приложение, соответствующим образом составив различные компоненты, с очень небольшим количеством шаблонов.

Это примерно та последовательность, в которой я хотел бы атаковать проблему, поскольку она широко представляет порядок зависимостей в вашем коде и, следовательно, подходит для разработки «снизу вверх». Хотя, конечно, в хорошем гибком / итеративном стиле вы, вероятно, рано или поздно будете продвигаться вперед к демонстрационному конечному продукту, а затем довольно часто возвращаться к предыдущим шагам для расширения функциональности или рефакторинга по мере необходимости.

p.s. Если вы последуете описанному выше подходу, я был бы очарован, услышав, сколько строк Clojure требуется, чтобы соответствовать функциональности 50 000 строк Java.

Обновление: поскольку этот пост был изначально написан, появилось несколько дополнительных инструментов / библиотек, которые относятся к категории "обязательно проверить":

  • Noir - веб-фреймворк, основанный на Ring.
  • Korma - очень хороший DSL для доступа к базам данных SQL.
person mikera    schedule 08.03.2011
comment
Nitpick re: Решите, какой из эталонных типов STM Clojure вы хотите использовать для управления каждой частью изменяемого состояния на уровне приложения: существует только один ссылочный тип STM. Другие IRef не используют STM. В противном случае выглядит солидным советом. - person ; 09.03.2011
comment
хммм ... Я считаю, что ссылки, агенты и атомы являются частью системы Clojure STM / concurrency. Например, все они поддерживают валидаторы, а агенты координируют транзакции. но я понимаю вашу точку зрения, ссылки - это основная транзакционная модель. сделаю быструю поправку. - person mikera; 09.03.2011
comment
Если бы я только мог поставить больше +1. Я посмотрел оба видео, на которые вы ссылались, и они были великолепны. Спасибо. - person jdl; 09.03.2011
comment
Теперь нуар устарел. Я полагаю, вы должны упомянуть о самообладании вместо нуара. - person hsestupin; 22.02.2013
comment
Ссылка One Ring To Bind Them не работает! - person Adam Arold; 28.04.2014

Какие аспекты Java включены в ваш текущий проект? Ведение журнала, транзакции базы данных, декларативные транзакции / EJB, веб-уровень (вы упомянули JSP, сервлеты) и т. Д. Я заметил, что экосистема Clojure имеет различные микро-фреймворки и библиотеки с целью выполнить одну задачу и сделать это хорошо. Я бы посоветовал оценить библиотеки в зависимости от ваших потребностей (и от того, будут ли они масштабироваться в крупных проектах) и принять обоснованное решение. (Отказ от ответственности: я являюсь автором bitumenframework) Еще одна вещь, на которую следует обратить внимание, это процесс сборки - если вам нужна сложная настройка (разработка, тестирование, постановка, продакшн), возможно, вам придется разбить проект на модули и для простоты написать сценарий процесса сборки.

person Shantanu Kumar    schedule 08.03.2011
comment
Сервлеты, JSP, самодельная структура персистентности (10 лет назад) и pojos, но без EJB - person yazz.com; 08.03.2011
comment
Сервлеты можно легко заменить на Ring + Compojure IMHO, а JSP можно заменить, возможно, StringTemplate (или шаблонами FreeMarker / Velocity). Постоянство в Clojure будет отличаться от Java. Если вам нужно реляционное сопоставление, вы можете посмотреть Clj-Record и SQLRat (пока не очень развиты). ClojureQL на данный момент поддерживает только MySQL и PostgreSQL, AFAICT. Текущее ограничение c.c.sql на запрет подчеркивания в именах столбцов может стать неожиданностью. Я думаю, что обсуждение аспектов разработки в списке Clojure по мере необходимости будет полезно. Удачи в проекте! - person Shantanu Kumar; 09.03.2011
comment
После этого проекта я сделал еще одно приложение с Clojure и Clojurescript (nemcv.com), и сейчас я использую Ring, попробовал ClojureQL, но переключился на Korma для доступа к базе данных. Вы можете увидеть последние работы на github.com/zubairq/coils - person yazz.com; 18.08.2013

Я обнаружил, что самое сложное - думать о базе данных. Проведите несколько тестов, чтобы найти нужные инструменты, которые вы хотите использовать.

person LenW    schedule 08.03.2011
comment
Я пробовал clojureql для доступа к данным, но он полностью отличается от стиля доступа к базе данных Java, который полностью основан на объектах. Просто ради интереса, какой доступ к базе данных вы использовали для Java и что вы использовали с Clojure? - person yazz.com; 08.03.2011
comment
В итоге мы переосмыслили многие вещи и перешли на mongodb, поскольку сохранение структур данных clojure было очень естественным. - person LenW; 11.03.2011