Mari gunakan hasil karya terdahulu yang sudah modular.

wget https://github.com/jpmrblood/percuma/archive/v2.zip -qO- | jar xvf /dev/stdin && cd percuma-2

Saat ini saya akan menggunakan metode decoupling berdasarkan tujuan (goal-based) versi yang telah disederhanakan. Tentu tidak akan serumit reverse engineering pada tulisan saya. Tulisan (Yu et al., 2005, 363--372) yang saya bahas itu rasanya terlalu rumit untuk dikembangkan di tulisan ini. Oke, sejujurnya saya juga sedang malas menggambar diagram.

Saya mengambil teknik Extract Method dari (Martin Fowler, 1999, 89--91) yang digunakan di awal metodologi itu. Agar sederhana, saya modifikasi metodologi agar menerjemahkan menjadi cerita (user story), bukan notasi ilmiah.

Contoh Metodologi Reverse Engineering Goal Based of JP, Abridge Version

Mari lihat kembali kelas yang telah dibuat sebelumnya.

package aja.jp.percuma;
 
class TestMain {
  public static void main (String ... args) {
    java.util.logging.Logger.getLogger(TestMain.class.getName()).info("Hello, world!");
  }
}

Apa yang dilakukan? Mari kita ceritakan dalam kalimat cerita:

Program ini mencetak ke terminal tulisan “Hello, world!”.

Dari cerita ini, ternyata ada dua tujuan yang terlihat jelas:

  1. Mencetak ke terminal.
  2. Tulisan “Hello, world!”.

Mencetak ke terminal (1) adalah sebuah tujuan yang bisa dibuat umum. Ada banyak hal yang bisa dilakukan dengan fungsi (1) ini. Fungsi ini bisa diekstraksi dan dijadikan sebuah fungsi terpisah agar bisa dimanfaatkan yang lainnya. Maka direkomendasikan agar (1) dijadikan fungsi terpisah.

Tulisan “Hello, world!” (2) adalah sebuah tujuan yang spesifik. Dia tidak bisa dipakai untuk yang lain. Maka, direkomendasikan untuk tetap untuk di sana.

Wow, Kisanak mungkin berpikir. Gampang juga, yah. Ternyata hanya begitu saja!

Kisanak salah! Ilmu ini masih versi disederhanakan (abridge version). Mari saya bukakan sedikit tentang tujuan tersirat (soft goal). Pada metodologi Reverse Engineering Goal Based of JP, salah satu yang diperhitungkan adalah tujuan tersirat (soft goal)!

Ada banyak tujuan tersirat yang kalau pada bahasa SDLC disebut sebagai non-functional requirement. Seandainya proyek ini ditentukan tujuannya (bahasa lainnya: Scrum Goal, non-functional requirement pada Waterfall, dan lain sebagainya tergantung paguyuban tempat Kisanak berguru). Pada iterasi selanjutnya, (2) dapat dikembangkan lebih lanjut, misalnya dengan menambahkan tujuan tersirat:

  1. Ingin menyapa bukan hanya dunia. Nama yang hendak disapa dapat diperoleh melalui STDIN (nama kerennya terminal). Rekomendasi: dibuatkan sebuah variabel dengan nilai baku “Hello, %s!”. Lalu, tangkap nama melalui STDIN. Masukkan nama ke senarai yang telah dibuat itu. Terakhir, cetak.
  2. Ingin agar ini dapat dimengerti hampir semua orang. Rekomendasi: dibuatkan variabel berisi “Hello” yang dianotasi dengan i18n. Gunakan framework lokalisasi.

Jangan lupa, bahwa bahkan pengumpulan kebutuhan dapat diiterasikan agar lebih jelas. Contohnya untuk tujuan tersirat (1). Diiterasikan kembali bahwa keamanan merupakan fitur utama. Tujuan tersirat (1), ditambahkan fungsi pengecekan Regex sebagai validasi sebelum memroses (1.1). Agar menarik, maka dibuatkan pemformat yang dapat menghasilkan keluaran yang cantik ke terminal (1.2).

Kisanak tentu bertanya, bagaimana cara menentukan tujuan tersirat ini? Sampai sedalam mana iterasi ini? Bisa jadi aplikasi menjadi besar dan bahkan untuk fungsi sederhana menjadi sulit. Itu sebabnya, biasanya tujuan tersirat biasanya dibuat di awal proyek dan berlaku global atau setidaknya dalam sebuah cakupan submodul. Beberapa perguruan silat membuat itu menjadi standar baku. Inilah yang dimaksud dengan Design Pattern bukan hanya berbicara kode, tetapi standar baku di sebuah perusahaan.

Astaga, sampai mana saya tadi?

Oh, iya, intinya, sudah saya jelaskan bahwa fungsi menulis ke terminal bisa diekstraksi ke fungsi lainnya. Karena dia bisa dipakai untuk yang lain, maka dia bisa dijadikan sebuah modul tersendiri. Pada proses penentuan modul, Kisanak dapat bisa mengenali apakah fungsi cetak ke terminal ini dijadikan proyek tersendiri sehingga bisa dimanfaatkan oleh proyek-proyek yang lainnya. Apalagi, dia tidak sesuai dengan tujuan proyek ini, membuat aplikasi percuma/sia-sia. Dia sudah sangat berguna sehingga tidak masuk lagi hitungan. Ha… ha… ha….

Mari Implementasikan ke Gradle

Setelah makanan bagi jiwa, sekarang saatnya ke Gradle. Pada direktori dasar proyek, mari buat submodul:

mkdir percuma-libs

Seperti biasa, masukkan percuma-libs ke proyek utama.

echo "include 'percuma-libs'" >> settings.gradle

Kalau benar, maka akan muncul sebagai submodul proyek percuma.

$ ./gradlew -q projects

------------------------------------------------------------
Root project
------------------------------------------------------------

Root project 'percuma'
+--- Project ':percuma-app'
\--- Project ':percuma-libs'

To see a list of the tasks of a project, run gradlew <project-path>:tasks
For example, try running gradlew :percuma-app:tasks

Buat konfigurasi untuk mengompilasi percuma-libs.

cat >> percuma-libs/build.gradle << EOF
apply plugin: 'java'
EOF

Sekarang, mari buat sebuah kelas Java.

mkdir -p percuma-libs/src/main/java/aja/jp/percuma/lib
cat >> percuma-libs/src/main/java/aja/jp/percuma/lib/PrintLib.java << EOF 
package aja.jp.percuma.lib;

public class PrintLib {
  public void log(Object o, String m) {
    java.util.logging.Logger.getLogger(o.getClass().getName()).info(m);
  }
}
EOF

Setelah membuat submodul ini, mari tambahkan submodul percuma-libs sebagai salah satu pustaka yang dibutuhkan oleh percuma-apps.

cat >> percuma-apps/build.gradle << EOF
dependencies {
  compile project(':percuma-libs')
}
EOF

Mari ubah kelas TestMain untuk menggunakan pustaka yang sudah kita masukkan. Ubah baris:

java.util.logging.Logger.getLogger(TestMain.class.getName()).info("Hello, world!");

menjadi:

new aja.jp.percuma.lib.PrintLib().log(new TestMain(),"Hello, world!");

Atau kalau dari terminal:

sed -i.bak "/java.util.logging.Logger/c\    new aja.jp.percuma.lib.PrintLib().log(new TestMain(),\"Hello, world\!\");" percuma-app/src/main/java/aja/jp/percuma/TestMain.java

Selesai sudah.

Judul Cuma untuk Pembatas Saja dan Saya Bingung Apa Namanya Karena Artikel Ini Bukan Artikel Terakhir Karena Entah Mengapa Kalau Saya Beri Nama Penutup Artikel Selanjutnya Tidak Pernah Jadi

Sampai sini, Kisanak bisa langsung menjalankan “./gradlew run” seperti biasa. Seharusnya, sih, keluarannya sama.

Sampai sini saya juga berpikir, apakah saya perlu mengubah gaya menulis saya? Saya biasanya menggunakan frasa, “silakan gunakan penyunting kesukaan Anda.” Kali ini saya paksakan semua kita menggunakan penyunting saya, terminal GNU/Linux.

Semuanya bisa langsung dicobakan di terminal pada sistem operasi GNU/Linux. Mohon beritahu saya kalau ada yang tidak jalan.

Selanjutnya

Kisanak berpikir setelah menguasai modularitas dengan Gradle dan metodologi cetek Reverse Engineering of JP, Abridge Version, Kisanak merasa sudah elit?

Sayang sekali, Kisanak. Kalau Kisanak sadar, cara penamaan paket saya kacau! Mana benar itu penulisan “aja.jp.percuma”? Seharusnya “edu.ui.jp.percuma” sesuai dengan organisasi yang jam kerjanya saya ambil untuk menulis ini atau “jp.percuma” karena “aja” bukanlah top level domain yang lazim. Pokoknya, konvensi penamaan ini penting.

Ah, Pak JP, apakah ada yang perlu saya pelajari? Mohon ajari, bila berkenan.

Saya suka sikap Kisanak! Nama paket akan sangat berpengaruh terhadap Artifak. Artifak adalah obyek-obyek hasil kultivasi yang banyak dipakai orang. Misalnya, menggunakan Maven dalam POM yang ada di JCenter atau Maven Repository.

Tergantung mood saya, saya akan membahas cara membuat peladen artifak lokal (bonus kalau saya lagi mood) dan  membuat artifak dengan Gradle dan mengimpor artifak dengan Gradle. Atau, mungkin hanya di sekitar artifak saja. Entahlah…. Film apa yang bagus untuk mood saya, ya?

Daftar Pustaka

Martin Fowler (1999). Refactoring: Improving the Design of Existing Code. Boston: Addison-Wesley Professional. doi: 0201485672 9780201485677. Retrieved from Addison-Wesley Professional: www.worldcat.org/isbn/0201485672.^
Yu, Yijun and Wang, Yiqiao and Mylopoulos, J. and Liaskos, S. and Lapouchnian, A. and Leite (2005, August). Reverse engineering goal models from legacy code 13th IEEE International Conference on Requirements Engineering (RE'05), [NO VOLUME]([NO ISSUE]), 363--372. doi: 10.1109/RE.2005.61.^