Saya baru saja diminta oleh perusahaan saya untuk menulis ulang aplikasi Java yang berukuran besar (50.000 baris kode) (aplikasi web menggunakan JSP dan servlet) di Clojure. Adakah orang lain yang mendapat tip tentang apa yang harus saya waspadai?
Harap diingat bahwa saya tahu Java DAN Clojure dengan cukup baik.
Memperbarui
Saya menulis ulang dan itu masuk ke produksi. Ini cukup aneh karena penulisan ulang berakhir begitu cepat sehingga selesai dalam waktu sekitar 6 minggu. Karena banyak fungsi yang tidak diperlukan, itu berakhir lebih seperti 3000 baris Clojure.
Saya mendengar mereka senang dengan sistem dan melakukan apa yang mereka inginkan. Satu-satunya downside adalah bahwa orang yang memelihara sistem harus mempelajari Clojure dari awal, dan dia diseret ke dalamnya sambil menendang dan menjerit. Saya memang mendapat telepon darinya beberapa hari yang lalu mengatakan dia mencintai Lisp sekarang .. lucu :)
Juga, saya harus memberi perhatian yang baik kepada Vaadin. Menggunakan Vaadin mungkin menyumbang sebanyak waktu yang dihemat dan sesingkat kode seperti yang dilakukan Clojure .. Vaadin masih merupakan kerangka kerja web teratas yang pernah saya gunakan, meskipun sekarang saya mempelajari ClojureScript dengan marah! (Perhatikan bahwa Vaadin dan ClojureScript menggunakan kerangka kerja GUI Google di bawah kap mesin.)
Jawaban:
"Masalah translasi" terbesar mungkin akan beralih dari metodologi Java / OOP ke paradigma pemrograman Clojure / fungsional.
Secara khusus, alih-alih memiliki keadaan yang dapat berubah dalam objek, "Cara Clojure" adalah dengan jelas memisahkan keadaan yang dapat berubah dan mengembangkan fungsi murni (bebas efek samping). Anda mungkin sudah mengetahui semua ini :-)
Bagaimanapun, filosofi ini cenderung mengarah pada sesuatu dari gaya pengembangan "bottom up" di mana Anda memfokuskan upaya awal pada membangun seperangkat alat yang tepat untuk memecahkan masalah Anda, lalu akhirnya menyatukannya di akhir. Ini mungkin terlihat seperti ini
Identifikasi struktur data utama dan ubah menjadi peta Clojure yang tidak dapat diubah atau definisi rekaman. Jangan takut untuk membuat banyak peta yang tidak dapat diubah - peta ini sangat efisien berkat struktur data yang persisten dari Clojure. Layak untuk menonton video ini untuk mempelajari lebih lanjut.
Kembangkan pustaka kecil yang murni, fungsi berorientasi logika bisnis yang beroperasi pada struktur yang tidak dapat diubah ini (misalnya "menambahkan item ke keranjang belanja"). Anda tidak perlu melakukan semua ini sekaligus karena mudah untuk menambahkan lebih banyak nanti, tetapi akan membantu jika melakukan beberapa di awal untuk memfasilitasi pengujian dan membuktikan bahwa struktur data Anda berfungsi ..... dengan cara apa pun dalam hal ini titik Anda benar-benar dapat mulai menulis hal-hal yang berguna secara interaktif di REPL
Kembangkan rutinitas akses data yang dapat mempertahankan struktur ini ke / dari database atau jaringan atau kode Java lama secara terpisah sesuai kebutuhan. Alasan untuk menjaga ini sangat terpisah adalah karena Anda tidak ingin logika ketekunan terikat dengan fungsi "logika bisnis" Anda. Anda mungkin ingin melihat ClojureQL untuk ini, meskipun juga cukup mudah untuk membungkus kode persistensi Java yang Anda suka.
Tulis tes unit (misalnya dengan clojure.test ) yang mencakup semua hal di atas. Hal ini sangat penting dalam bahasa dinamis seperti Clojure karena a) Anda tidak memiliki banyak jaring pengaman dari pemeriksaan tipe statis dan b) ini membantu untuk memastikan bahwa konstruksi tingkat yang lebih rendah berfungsi dengan baik sebelum Anda membangun terlalu banyak di atasnya. di atas mereka
Putuskan bagaimana Anda ingin menggunakan jenis referensi Clojure (vars, ref, agen, dan atom) untuk mengelola setiap bagian status tingkat aplikasi yang dapat berubah. Mereka semua bekerja dengan cara yang serupa tetapi memiliki semantik transaksional / konkurensi yang berbeda tergantung pada apa yang Anda coba lakukan. Referensi mungkin akan menjadi pilihan default Anda - mereka mengizinkan Anda untuk mengimplementasikan perilaku transaksional STM "normal" dengan membungkus kode apa pun dalam blok (dosync ...).
Pilih keseluruhan kerangka kerja web yang tepat - Clojure sudah memiliki cukup banyak, tetapi saya sangat menyarankan Ring - lihat video yang luar biasa ini " One Ring To Bind Them " plus Fleet atau Enlive atau Hiccup tergantung pada filosofi templating Anda. Kemudian gunakan ini untuk menulis lapisan presentasi Anda (dengan fungsi seperti "terjemahkan keranjang belanja ini ke dalam fragmen HTML yang sesuai")
Terakhir, tulis aplikasi Anda menggunakan alat di atas. Jika Anda telah melakukan langkah-langkah di atas dengan benar, maka ini akan menjadi sedikit yang mudah karena Anda akan dapat membangun seluruh aplikasi dengan komposisi yang sesuai dari berbagai komponen dengan boilerplate yang sangat sedikit.
Ini kira-kira urutan yang saya akan menyerang masalah karena secara luas mewakili urutan dependensi dalam kode Anda, dan karenanya cocok untuk upaya pengembangan "bottom up". Meskipun tentu saja dalam gaya gesit / iteratif yang baik Anda mungkin akan menemukan diri Anda mendorong lebih awal ke produk akhir yang dapat dibuktikan dan kemudian melompat kembali ke langkah sebelumnya cukup sering untuk memperluas fungsionalitas atau refactor sesuai kebutuhan.
ps Jika Anda mengikuti pendekatan di atas, saya akan terpesona mendengar berapa banyak baris Clojure yang diperlukan untuk mencocokkan fungsionalitas 50.000 baris Java
Pembaruan : Sejak posting ini awalnya ditulis, beberapa alat / perpustakaan tambahan telah muncul yang berada dalam kategori "harus diperiksa":
sumber
Aspek apa dari Java yang termasuk dalam proyek Anda saat ini? Logging, Transaksi database, Transaksi deklaratif / EJB, lapisan web (Anda menyebutkan JSP, servlet) dll. Saya telah memperhatikan ekosistem Clojure memiliki berbagai kerangka kerja mikro dan perpustakaan dengan tujuan untuk melakukan satu tugas, dan melakukannya dengan baik. Saya menyarankan untuk mengevaluasi perpustakaan berdasarkan kebutuhan Anda (dan apakah itu akan meningkatkan skala dalam proyek-proyek besar) dan membuat keputusan yang tepat. (Disclaimer: Saya penulis bitumenframework ) Satu hal yang perlu diperhatikan adalah proses membangun - jika Anda memerlukan setup yang kompleks (dev, pengujian, pementasan, prod) Anda mungkin harus membagi proyek ke dalam modul dan memiliki proses membangun scripted untuk meredakan.
sumber
Saya menemukan bagian tersulit adalah memikirkan tentang database. Lakukan beberapa pengujian untuk menemukan alat yang tepat yang ingin Anda gunakan di sana.
sumber