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


97

Мене щойно попросили моя компанія переписати велику (50 000 одиночних рядків коду) програми Java (веб-додаток, що використовує JSP та сервлети) у Clojure. Хто-небудь ще отримав поради щодо того, на що я повинен стежити?

Будь ласка, майте на увазі, що я добре знаю і Java, і Clojure.

Оновлення

Я зробив перезапис, і це пішло у виробництво. Це досить дивно, оскільки перезапис закінчився настільки швидко, що це було зроблено приблизно за 6 тижнів. Оскільки багато функціональних можливостей не було потрібно, все одно це закінчилося більше як 3000 рядків Clojure.

Я чую, що вони задоволені системою та її виконанням саме того, що вони хотіли. Єдиним недоліком є ​​те, що хлопець, що підтримує систему, повинен був навчитися Clojure з нуля, і його затягнули в нього ударами та криками. Днями мені зателефонували від нього, сказавши, що він зараз любить Ліспа .. смішно :)

Також я мушу добре згадати Ваадіна. Використання Vaadin, ймовірно, займало стільки ж заощадженого часу та нестачі коду, скільки Clojure. Це Vaadin як і раніше найкраща веб-основа, яку я коли-небудь використовував, хоча зараз я гнівно вивчаю ClojureScript! (Зверніть увагу, що і Vaadin, і ClojureScript використовують графічний інтерфейс Google під капотом.)


55
Я хочу працювати для вашої компанії.
мтьяка

4
Ну, деякі оборонні компанії в Європі почали використовувати Clojure (я чув). Але не можу згадати жодних імен :)
appshare.co

1
@Zubair: 50 000 Java LOC не наближається до "великих". Це дуже маленький проект. У мене тут є проект Java від 250KLOC до 300KLOC, і він середнього розміру ... У кращому випадку.
SyntaxT3rr0r

5
Насправді я, можливо, припустився помилки, згадавши розмір кодової бази, бо справедливості заради зменшення розміру коду не є метою перезапису. Метою є подвійне: 1) зробити базу коду більш зрозумілою і, таким чином, дешевше підтримувати код 2) Дозволити користувачам інструменту розширювати продукт за допомогою редактора Clojure у веб-браузері (використовуючи eval та інші динамічні якості Clojure, які дорожче do in Java)
appshare.co

1
Гей ... щойно побачив це старе питання і цікавився, як переписується?
леваі

Відповіді:


82

Найбільша "поступальна проблема", ймовірно, буде переходити від методології Java / OOP до парадигми Clojure / функціонального програмування.

Зокрема, замість того, щоб змінювати стан об'єктів, що змінюються, об'єкти, "спосіб Clojure" - це чітко відокремити стан, що змінюється, та розробити чисті (без побічних ефектів) функції. Ви, напевно, все це вже знаєте :-)

У будь-якому випадку ця філософія має тенденцію вести до чогось стилю розвитку "знизу вгору", де ви орієнтуєтеся на початкові зусилля над створенням правильного набору інструментів для вирішення своєї проблеми, а потім, нарешті, з'єднайте їх у кінці. Це може виглядати приблизно так

  1. Визначте основні структури даних та перетворіть їх на незмінні карти Clojure або записуйте записи. Не бійтеся вкладати безліч незмінних карт - вони дуже ефективні завдяки стійким структурам даних Clojure. Варто переглянути це відео, щоб дізнатись більше.

  2. Розробіть невеликі бібліотеки з чистими, орієнтованими на ділову логіку функціями, які працюють на цих незмінних структурах (наприклад, "додати товар у кошик"). Вам не потрібно робити все це одночасно, оскільки їх легко додати пізніше, але це допомагає зробити кілька на ранніх етапах, щоб полегшити тестування та довести, що ваші структури даних працюють ... Точка ви можете почати писати корисні речі інтерактивно в REPL

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

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

  5. Вирішіть, як ви хочете використовувати еталонні типи Clojure (vars, refs, агенти та атоми) для управління кожною частиною, що змінюється станом рівня програми. Всі вони працюють аналогічно, але мають різну семантику транзакцій / одночасності залежно від того, що ви намагаєтесь зробити. Посилання, мабуть, будуть вашим вибором за замовчуванням - вони дозволять вам реалізувати "звичайну" поведінку транзакцій STM, обертаючи будь-який код у блок (dosync ...).

  6. Виберіть правильний загальний веб - фреймворк - Clojure має досить багато вже , але я настійно рекомендую кільце - подивитися відмінне відео « Одне Кільце , щоб зв'язати їх » плюс або Fleet або Enlive або гикавка в залежності від вашої філософії шаблонною. Потім використовуйте це для написання презентаційного шару (з такими функціями, як "перекласти цей кошик у відповідний фрагмент HTML")

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

Це приблизно та послідовність, яку я б атакував на проблему, оскільки вона в цілому представляє порядок залежностей у вашому коді, а значить, підходить для розробки "знизу вгору". Хоча, звичайно, у хорошому гнучкому / ітераційному стилі, ви, мабуть, виявите себе, що рано просуваєтесь до демонструваного кінцевого продукту, а потім досить часто переходите до попередніх кроків, щоб розширити функціональність або рефакторинг за необхідності.

ps Якщо ви дотримуєтесь вищезазначеного підходу, я був би захоплений, почувши, скільки рядків Clojure потрібно, щоб відповідати функціональності 50 000 рядків Java

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

  • Noir - веб-рамка, яка будується поверх Ring.
  • Корма - дуже приємний DSL для доступу до баз даних SQL.

4
Nitpick re: "Визначте, який із еталонних типів STM Clojure ви хочете використовувати для управління станом рівня додатків, що змінюються, частиною програми": Є лише один посилання типу STM. Інші IRefs не включають STM. В іншому випадку це виглядає як тверда порада.

хммм ... Я думаю, я вважаю, що реф, агенти та атоми є частиною системи Clojure STM / паралельної конкуренції. Наприклад, всі вони підтримують валідатори, а агенти координуються з комітами транзакцій. але я розумію вашу думку, посилання - це "основна" модель транзакцій. внесе швидку поправку.
mikera

2
Якби тільки я міг дати це ще +1. Я переглянув обидва відео, на які ви посилалися, і вони були чудовими. Дякую.
jdl

1
Зараз нуар застарілий. Я думаю, вам доведеться згадати про композиторство, а не про нуар.
hsestupin

Посилання One Ring To Bind Them розірвано!
Адам Арольд

5

Які аспекти Java включає ваш поточний проект? Ведення журналів, транзакції бази даних, деклараційні транзакції / EJB, веб-шар (ви згадали JSP, сервлети) тощо. Я помітив, що екосистема Clojure має різні мікро-рамки та бібліотеки, які мають на меті виконати одне завдання, і зробіть це добре. Я пропоную оцінити бібліотеки, виходячи з ваших потреб (і чи буде це масштабуватись у великих проектах), і прийняти зважене рішення. (Відмова: Я є автором бітумної рамки ) Ще одна річ, яку слід зазначити, це процес збирання - якщо вам потрібна складна установка (dev, тестування, постановка, prod), можливо, вам доведеться розділити проект на модулі і сценарій збирання сценарій для легкість.


Servlets, JSP, побудована система збереження вдома (10 років) і pojos, але немає EJB
appshare.co

4
Сервлетів можна легко замінити на Ring + Compojure IMHO, а JSP можна замінити, можливо, StringTemplate (або шаблони FreeMarker / Velocity.) Наполегливість у Clojure буде відрізнятися від Java. Якщо вам потрібно реляційне відображення, ви можете подивитися Clj-Record і SQLRat (ще не дуже зрілі). На даний момент ClojureQL підтримує лише MySQL та PostgreSQL AFAICT. Поточне обмеження в ccsql для заборони підкреслення в назвах стовпців може стати несподіванкою. Я думаю, що обговорення аспектів розвитку у списку Clojure як необхідне буде корисним. Успіхів у проекті!
Шантану Кумар

З цього проекту я зробив ще одну програму з Clojure та Clojurescript (nemcv.com), і зараз я використовую Ring, спробував ClojureQL, але перейшов до Korma для доступу до бази даних. Ви можете побачити останні роботи на github.com/zubairq/coils
appshare.co

4

Мені здалося, що найскладніша частина була думка про базу даних. Зробіть кілька тестів, щоб знайти потрібні інструменти, які ви хочете використовувати там.


1
Добре я спробував clojureql для доступу до даних, але він абсолютно відрізняється від стилю Java до бази даних, який базується на всіх об'єктах. Нецікаво, який доступ до бази даних ви використовували для Java та що ви використовували з Clojure?
appshare.co

1
Ми закінчили переосмислити багато речей і піти з mongodb, оскільки збереження даних про clojure було дуже природно
ЛНВ
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.