Java'dan Clojure'a yeniden yazma


97

Şirketim, Clojure'da büyükçe (50.000 tek satırlık kod) bir Java uygulamasını (JSP ve sunucu uygulamaları kullanan bir web uygulaması) yeniden yazmamı istedi. Nelere dikkat etmem gerektiğine dair başka ipuçları olan var mı?

Lütfen hem Java hem de Clojure'u oldukça iyi bildiğimi unutmayın.

Güncelleme

Yeniden yazdım ve üretime geçti. Yeniden yazma işlemi o kadar hızlı gitti ki yaklaşık 6 hafta içinde yapıldı. Çok fazla işlevselliğe ihtiyaç duyulmadığından, 3000 Clojure satırına benziyordu.

Sistemden memnun olduklarını ve tam olarak istediklerini yaptıklarını duydum. Tek dezavantajı, sistemi sürdüren kişinin Clojure'u sıfırdan öğrenmesi gerektiğiydi ve tekmeleyerek ve çığlık atarak içine sürüklendi. Geçen gün ondan Lisp'i sevdiğini söyleyen bir telefon aldım ama .. komik :)

Ayrıca Vaadin'den de iyi bahsetmeliyim. Vaadin'i kullanmak, muhtemelen kazanılan zamanın büyük bir kısmını ve Clojure'un yaptığı gibi kodun kısalığını oluşturuyordu .. Vaadin, hala ClojureScript'i öfkeyle öğrenmeme rağmen, şimdiye kadar kullandığım en iyi web çerçevesi. (Hem Vaadin hem de ClojureScript'in, başlık altında Google'ın GUI çerçevelerini kullandığını unutmayın.)


55
Şirketiniz için çalışmak istiyorum.
mtyaka

4
Avrupa'daki bazı savunma şirketleri Clojure'u kullanmaya başladı (duydum). Ama hiçbir ismi hatırlayamıyorum :)
appshare.co

1
@Zubair: 50 000 Java LOC, "büyük" e yakın değil. Bu çok küçük bir proje. Burada 250KLOC ile 300KLOC arası bir Java projem var ve orta büyüklükte ... En iyi ihtimalle.
SözdizimiT3rr0r

5
Aslında, kod tabanının boyutundan bahsederek, kod boyutunda bir küçültmenin yeniden yazmanın amacı olmadığını söyleyerek bir hata yapmış olabilirim. Amaç iki yönlüdür: 1) kod tabanının daha anlaşılır olması ve dolayısıyla kodu sürdürmenin daha ucuz olması 2) Aracın kullanıcılarının ürünü web tarayıcısında bir Clojure editörü kullanarak genişletmesine izin verin (eval ve diğer dinamik Clojure iyiliklerini kullanarak daha maliyetli olan Java'da yapmak)
appshare.co

1
Hey ... az önce bu eski soruyu gördüm ve yeniden yazmanın nasıl gittiğini merak ediyor muydun?
levand

Yanıtlar:


82

En büyük "çeviri sorunu" muhtemelen bir Java / OOP metodolojisinden Clojure / işlevsel programlama paradigmasına gidecek.

Özellikle, nesneler içinde değişebilir duruma sahip olmak yerine, "Clojure yolu", değişebilir durumu açıkça ayırmak ve saf (yan etkisiz) işlevler geliştirmektir. Muhtemelen bunların hepsini zaten biliyorsunuz :-)

Her neyse, bu felsefe, probleminizi çözmek için doğru araçlar setini oluşturmaya ilk çabalarınızı odakladığınız ve sonunda bunları sonunda birleştirdiğiniz "aşağıdan yukarıya" bir geliştirme tarzına yönelme eğilimindedir. Bu böyle bir şeye benzeyebilir

  1. Temel veri yapılarını tanımlayın ve bunları değişmez Clojure haritasına veya kayıt tanımlarına dönüştürün. Çok sayıda değişmez haritayı iç içe yerleştirmekten korkmayın - Clojure'un kalıcı veri yapıları sayesinde çok verimlidirler. Daha fazlasını öğrenmek için bu videoyu izlemeye değer .

  2. Bu değişmez yapılar üzerinde çalışan saf, iş mantığı odaklı işlevlerden oluşan küçük kitaplıklar geliştirin (ör. "Alışveriş sepetine bir öğe ekle"). Daha sonra daha fazlasını eklemek kolay olduğu için bunların hepsini aynı anda yapmanız gerekmez, ancak testi kolaylaştırmak ve veri yapılarınızın çalıştığını kanıtlamak için erken bir kaç adım yapmak yardımcı olur ..... her iki şekilde de REPL'de gerçekten etkileşimli olarak yararlı şeyler yazmaya başlayabilirsiniz.

  3. Gerektiğinde bu yapıları veritabanına veya ağa veya eski Java koduna / veritabanından devam ettirebilen veri erişim rutinlerini ayrı ayrı geliştirin. Bunu çok ayrı tutmanın nedeni, kalıcılık mantığının "iş mantığı" işlevlerinizle bağlantılı olmasını istememenizdir. Bunun için ClojureQL'e bakmak isteyebilirsiniz , ancak beğendiğiniz herhangi bir Java kalıcı kodunu paketlemek oldukça kolaydır.

  4. Yukarıdakilerin tümünü kapsayan birim testleri (örn. Clojure.test ile ) yazın . Bu özellikle Clojure gibi dinamik bir dilde önemlidir, çünkü a) statik tip kontrolünden çok fazla bir güvenlik ağına sahip değilsinizdir ve b) çok fazla şey inşa etmeden önce alt düzey yapılarınızın iyi çalıştığından emin olmanıza yardımcı olur. üstleri

  5. Her bir parçanın değiştirilebilir uygulama düzeyi durumunu yönetmek için Clojure'un referans türlerini (değişkenler, başvurular, aracılar ve atomlar) nasıl kullanmak istediğinize karar verin. Hepsi benzer şekilde çalışır, ancak ne yapmaya çalıştığınıza bağlı olarak farklı işlem / eşzamanlılık anlamlarına sahiptir. Referanslar muhtemelen varsayılan seçiminiz olacaktır - herhangi bir kodu bir (dosync ...) bloğuna sararak "normal" STM işlem davranışını uygulamanıza izin verirler.

  6. Doğru genel web çerçevesini seçin - Clojure'da zaten birkaç tane var, ancak Ring'i şiddetle tavsiye ederim - bu mükemmel videoyu " Onları Bağlamak İçin Bir Yüzük " ve şablon oluşturma felsefenize bağlı olarak Fleet veya Enlive veya Hiccup izleyin. Ardından, sunum katmanınızı yazmak için bunu kullanın ("bu alışveriş sepetini uygun bir HTML parçasına çevir" gibi işlevlerle)

  7. Son olarak, yukarıdaki araçları kullanarak uygulamanızı yazın. Yukarıdaki adımları doğru bir şekilde yaptıysanız, bu aslında kolay olan bit olacaktır çünkü uygulamanın tamamını, çok az standart metne sahip çeşitli bileşenlerin uygun bileşimi ile oluşturabileceksiniz.

Bu, kabaca, kodunuzdaki bağımlılıkların sırasını geniş bir şekilde temsil ettiği için soruna saldıracağım sıradır ve bu nedenle "aşağıdan yukarıya" bir geliştirme çabası için uygundur. Elbette iyi çevik / yinelemeli tarzda olsa da, muhtemelen kendinizi gösterilebilir bir son ürüne erken doğru ilerlerken ve daha sonra işlevselliği genişletmek veya gerektiği gibi yeniden düzenlemek için oldukça sık önceki adımlara geri dönerken bulursunuz.

ps Yukarıdaki yaklaşımı izlerseniz, 50.000 satır Java'nın işlevselliğine uyması için kaç Clojure satırının gerektiğini duymak beni şaşırtabilir.

Güncelleme : Bu gönderi başlangıçta yazıldığından beri, "kontrol edilmesi gerekenler" kategorisinde birkaç ekstra araç / kitaplık ortaya çıktı:

  • Noir - Ring'in üzerine inşa edilen web çerçevesi.
  • Korma - SQL veritabanlarına erişmek için çok güzel bir DSL.

4
Nitpick re: "Clojure'ün STM referans türlerinden hangisini, her bir parçanın değiştirilebilir uygulama düzeyi durumunu yönetmek için kullanmak istediğinize karar verin": Yalnızca bir STM referans türü vardır. Diğer IRef'ler STM'yi içermiyor. Aksi takdirde sağlam bir tavsiye gibi görünüyor.

hmmm ... Referansları, ajanları ve atomları Clojure STM / eşzamanlılık sisteminin bir parçası olarak sayıyorum sanırım. Örneğin, hepsi doğrulayıcıları destekler ve aracılar işlem taahhütleriyle koordine edilir. ama anladığım kadarıyla, referanslar "birincil" işlem modelidir. hızlı bir değişiklik yapacak.
mikera

2
Keşke buna daha fazla +1 verebilseydim. Referans verdiğiniz iki videoyu da izledim ve harikaydı. Teşekkürler.
jdl

1
Artık noir kullanımdan kaldırıldı. Sanırım noir yerine compojure'den bahsetmelisiniz.
hsestupin

Onları Bağlayacak Bir Yüzük bağlantısı koptu!
Adam Arold

5

Mevcut projeniz Java'nın hangi yönlerini içeriyor? Günlüğe kaydetme, Veritabanı işlemleri, Bildirime dayalı işlemler / EJB, web katmanı (JSP'den, sunucu uygulamalardan bahsetmiştiniz) vb. Clojure eko-sisteminin tek bir görevi yerine getirmek ve bunu iyi yapmak amacıyla çeşitli mikro çerçevelere ve kitaplıklara sahip olduğunu fark ettim. Kütüphaneleri ihtiyacınıza göre (ve büyük projelerde ölçeklenip ölçeklenmeyeceğini) değerlendirmenizi ve bilinçli bir karar vermenizi öneririm. (Feragatname: Bitumenframework yazarıyım ) Dikkat edilmesi gereken bir diğer nokta da inşa sürecidir - karmaşık bir kuruluma (geliştirme, test etme, aşamalandırma, prod) ihtiyacınız varsa, projeyi modüllere ayırmanız ve derleme sürecini komut dosyası haline getirmeniz gerekebilir. kolaylaştırmak.


Servletler, JSP, evde yerleşik kalıcılık çerçevesi (10 yaşında) ve pojos, ancak EJB yok
appshare.co

4
Sunucular kolayca Ring + Compojure IMHO ile değiştirilebilir ve JSP'ler belki StringTemplate (veya FreeMarker / Velocity şablonları) ile değiştirilebilir. Clojure'da Kalıcılık Java'dan farklı olacaktır. İlişkisel haritalamaya ihtiyacınız varsa, Clj-Record ve SQLRat'a bakabilirsiniz (henüz çok olgun değil). ClojureQL şu anda yalnızca MySQL ve PostgreSQL'i AFAICT desteklemektedir. Ccsql'nin sütun adlarında alt çizgilere izin vermeme konusundaki mevcut sınırlaması bir sürpriz olabilir. Clojure listesindeki geliştirme yönlerini gerektiği gibi ve gerektiğinde tartışmanın faydalı olacağını düşünüyorum. Projede iyi şanslar!
Shantanu Kumar

O projeden beri Clojure ve Clojurescript (nemcv.com) ile başka bir uygulama yaptım ve şimdi Ring kullanıyorum, ClojureQL'i denedim, ancak veritabanı erişimi için Korma'ya geçiyorum. Son çalışmayı github.com/zubairq/coils
appshare.co

4

En zor kısmın veritabanı hakkında düşünmek olduğunu buldum. Orada kullanmak istediğiniz doğru araçları bulmak için bazı testler yapın.


1
Veri erişimi için clojureql'i denedim, ancak tamamen nesne tabanlı olan Java tarzı veritabanı erişiminden tamamen farklı. Java için hangi veritabanı erişimini kullandınız ve Clojure ile ne kullandınız?
appshare.co

1
Tıkanma veri yapılarının kalıcılığı çok doğal olduğu için birçok şeyi yeniden düşündük ve mongodb ile devam ettik
LenW
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.