Moja firma właśnie poprosiła mnie o przepisanie dużej (50 000 pojedynczych linii kodu) aplikacji Java (aplikacji internetowej korzystającej z JSP i serwletów) w Clojure. Czy ktoś jeszcze ma wskazówki, na co powinienem uważać?
Pamiętaj, że dobrze znam zarówno Javę, jak i Clojure.
Aktualizacja
Zrobiłem przepisanie i weszło do produkcji. To dość dziwne, ponieważ przepisywanie skończyło się tak szybko, że zostało zrobione w około 6 tygodni. Ponieważ wiele funkcji nie było potrzebnych, skończyło się bardziej na 3000 linii Clojure.
Słyszałem, że są zadowoleni z systemu i robi dokładnie to, czego chcieli. Jedynym minusem jest to, że facet obsługujący system musiał nauczyć się Clojure od zera i został w to wciągnięty kopiąc i krzycząc. Niedawno zadzwonił do mnie, mówiąc, że teraz kocha Lispa ... zabawne :)
Powinienem też wspomnieć o Vaadinie. Używanie Vaadina prawdopodobnie przyczyniło się do zaoszczędzenia czasu i skrócenia kodu, tak jak Clojure. Vaadin jest nadal najlepszym frameworkiem internetowym, jakiego kiedykolwiek używałem, chociaż teraz uczę się ClojureScript w złości! (Zwróć uwagę, że zarówno Vaadin, jak i ClojureScript używają struktur GUI Google pod maską).
Odpowiedzi:
Największym „problemem translacyjnym” będzie prawdopodobnie przejście od metodologii Java / OOP do paradygmatu Clojure / programowania funkcjonalnego.
W szczególności, zamiast mieć zmienny stan w obiektach, „sposób Clojure” polega na wyraźnym oddzieleniu zmiennego stanu i opracowaniu czystych (wolnych od skutków ubocznych) funkcji. Prawdopodobnie już to wszystko wiesz :-)
W każdym razie ta filozofia prowadzi do czegoś w rodzaju stylu rozwoju „oddolnego”, w którym początkowe wysiłki koncentrują się na budowaniu odpowiedniego zestawu narzędzi do rozwiązania problemu, a na końcu łączą je razem. To może wyglądać mniej więcej tak
Zidentyfikuj kluczowe struktury danych i przekształć je w niezmienną mapę Clojure lub definicje rekordów. Nie bój się zagnieżdżać wielu niezmiennych map - są one bardzo wydajne dzięki trwałym strukturom danych Clojure. Warto obejrzeć ten film, aby dowiedzieć się więcej.
Twórz małe biblioteki czystych funkcji zorientowanych na logikę biznesową, które działają na tych niezmiennych strukturach (np. „Dodaj pozycję do koszyka”). Nie musisz robić tego wszystkiego naraz, ponieważ później łatwo jest dodać więcej, ale warto zrobić kilka na początku, aby ułatwić testowanie i udowodnić, że struktury danych działają ..... tak czy inaczej w rzeczywistości możesz zacząć interaktywnie pisać przydatne rzeczy w REPL
Oddzielnie opracuj procedury dostępu do danych, które w razie potrzeby mogą utrwalać te struktury do / z bazy danych lub sieci lub starszego kodu Java. Powodem, dla którego należy to bardzo oddzielić, jest to, że nie chcesz, aby logika trwałości była powiązana z funkcjami „logiki biznesowej”. W tym celu możesz spojrzeć na ClojureQL , chociaż dość łatwo jest opakować dowolny kod trwałości Java, który chcesz.
Napisz testy jednostkowe (np. Za pomocą clojure.test ), które obejmują wszystkie powyższe. Jest to szczególnie ważne w dynamicznym języku, takim jak Clojure, ponieważ a) nie masz tak dużej siatki bezpieczeństwa przed statycznym sprawdzaniem typów i b) pomaga upewnić się, że konstrukcje niższego poziomu działają dobrze, zanim zaczniesz zbyt dużo budować górę z nich
Zdecyduj, w jaki sposób chcesz używać typów referencyjnych Clojure (zmiennych, referencji, agentów i atomów) do zarządzania stanami poziomu aplikacji, które można modyfikować. Wszystkie działają w podobny sposób, ale mają inną semantykę transakcyjną / współbieżną w zależności od tego, co próbujesz zrobić. Domyślnym wyborem będą prawdopodobnie odwołania - pozwalają one na implementację „normalnego” zachowania transakcyjnego STM poprzez zawijanie dowolnego kodu w blok (dosync ...).
Wybierz właściwą ogólne ramy internetowej - Clojure ma już całkiem sporo, ale bym zalecamy Ring - zobacz ten doskonały film „ Jeden, by związać ” plusa albo Fleet lub Enlive lub Czkawka zależności od filozofii szablonów. Następnie użyj tego do napisania swojej warstwy prezentacji (z funkcjami takimi jak „przetłumacz ten koszyk na odpowiedni fragment HTML”)
Na koniec napisz swoją aplikację przy użyciu powyższych narzędzi. Jeśli poprawnie wykonałeś powyższe kroki, będzie to faktycznie łatwe, ponieważ będziesz w stanie zbudować całą aplikację poprzez odpowiedni skład różnych komponentów z bardzo małą ilością gotówki.
Jest to z grubsza kolejność, w której chciałbym zaatakować problem, ponieważ ogólnie reprezentuje on porządek zależności w Twoim kodzie, a zatem nadaje się do tworzenia „od podstaw”. Chociaż oczywiście w dobrym, zwinnym / iteracyjnym stylu, prawdopodobnie szybko przechodzisz do przodu do możliwego do udowodnienia produktu końcowego, a następnie często wracasz do wcześniejszych kroków, aby rozszerzyć funkcjonalność lub refaktoryzację w razie potrzeby.
ps Jeśli zastosujesz się do powyższego podejścia, byłbym zafascynowany tym, ile linii Clojure potrzeba, aby dopasować funkcjonalność 50000 linii Java
Aktualizacja : ponieważ ten post został pierwotnie napisany, pojawiło się kilka dodatkowych narzędzi / bibliotek, które należą do kategorii „trzeba sprawdzić”:
źródło
Jakie aspekty języka Java obejmuje Twój obecny projekt? Rejestrowanie, transakcje w bazie danych, transakcje deklaratywne / EJB, warstwa WWW (wspomniałeś o JSP, serwletach) itp. Zauważyłem, że ekosystem Clojure ma różne mikro-frameworki i biblioteki, których celem jest wykonanie jednego zadania i robi to dobrze. Proponuję ocenić biblioteki w oparciu o Twoje potrzeby (i czy będzie to skalowalne w dużych projektach) i podjąć świadomą decyzję. (Zastrzeżenie: jestem autorem bitumenframework ) Inną rzeczą, na którą należy zwrócić uwagę, jest proces kompilacji - jeśli potrzebujesz złożonej konfiguracji (programowanie, testowanie, staging, prod) może być konieczne podzielenie projektu na moduły i skrypty procesu kompilacji łatwość.
źródło
Najtrudniejszą częścią było myślenie o bazie danych. Wykonaj kilka testów, aby znaleźć odpowiednie narzędzia, których chcesz tam użyć.
źródło