Category Archives

3 Articles
Dao Modularitas: Contoh Kasus Penggunaan Modul Untuk Decoupling Dengan Gradle

Dao Modularitas: Contoh Kasus Penggunaan Modul Untuk Decoupling Dengan Gradle

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.^
Membuat Sub Modul pada Gradle Sebagai Lanjutan Tulisan Iseng Kemarin Karena Mood Saya Enak Setelah Puas Menonton Warcraft Kemarin

Membuat Sub Modul pada Gradle Sebagai Lanjutan Tulisan Iseng Kemarin Karena Mood Saya Enak Setelah Puas Menonton Warcraft Kemarin

Kisanak pikir setelah mengerti jurus Kunyuk Melempar Pisang, Kisanak sudah bisa menguasai dunia persilatan? Kisanak harus mawas diri dan mengerti bahwa di atas langit masih ada langit lagi. Jurus itu mungkin bisa membuat Anda selamat di dunia persilatan. Camkan ini:

Di atas langit masih ada langit; ilmu yang dikuasai hanyalah setitik dari samudera.

Ketika aplikasi yang dibuat hanya sederhana, ilmu jurus Kunyuk Melempar Pisang sudah cukup. Masalah baru ketahuan setelah Kisanak naik level dengan aplikasi yang besar dan kompleksitas tinggi. Niscaya Kisanak akan menemukan bahwa Kisanak hanyalah jawara kampung.

Untuk dapat merajai dunia persilatan, ada konsep lain yang Kisanak mesti pahami: modularitas.

Kisanak harus bisa memilah. Mana yang kekhususannya untuk menghadapi basisdata. Mana yang kekhususannya menampilkan dan memroses laman web. Mana kekhususannya mengurusi logaritma. Dan berbagai kekhususan lainnya. Dengan memahami kekhususan ini, Kisanak bisa melakukan dua konsep ini: reuse dan melacak ketergantungan.

Reuse, adalah konsep sakral pemrograman. Seperti pemeo berkata, “do not invent the wheels.” Kode yang baik adalah yang bisa memisahkan dengan baik fungsi-fungsi dalam berkas/proyek terpisah sehingga dapat dimanfaatkan oleh banyak pihak. Proses untuk mengubah dari kode yang kompleks dan rumit menjadi terpecah-pecah dan modular ini disebut proses decoupling.

Decoupling adalah sebuah Dao yang mendalam. Banyak yang berusaha menemukan misteri dibaliknya. Sedikit yang dapat menguasai Dao ini. Mereka yang telah mencapai pencerahan, merekalah sesungguhnya yang merajai dunia persilatan!

Di dunia persilatan, ada beberapa ilmu kanuragan untuk decoupling. Ada yang memiliki karma tinggi sehingga bisa mampu menguasai level tinggi menggunakan ilmu Pemrograman Dinamis (Dynamic Programming), ilmu Kalkulus Lambda (Lambda Programming), dan lain-lain. Banyak juga orang yang tergabung dalam sekte-sekte yang memiliki repositori Dao mendalam. Mereka ini banyak mengkultivasi ilmu Design Pattern. Pernah ada legenda bahwa sebuah ilmu ilmu legendaris yang sepertinya hilang ditelan bumi seperti KAOS bisa menguasai penuh Dao ini.

Sayangnya, untuk orang-orang biasa, yang paling banyak dikultivasi orang adalah variasi ilmu Tebak-tebak Berhadiah. Ilmu ini mudah dikuasai, namun ia takkan mampu memberikan pencerahan sampai menguasai seluruh Dao. Itu sebabnya, bagi orang-orang kebanyakan, mukadimah ini semua tidak berguna.

Mereka akan mengira bahwa apa yang ditulis ini hanyalah mengisi luang supaya entri ini banyak. Camkanlah satu rahasia langit ini, Kisanak: tutorial ini hanyalah gerbang menuju Dao decoupling. Yang perlu dipahami selanjutnya adalah melatih pikiran.

Melatih jiwa, melatih raga. Melatih roh, melatih kode. Lepas dari Samsara, lepas dari debug tak berakhir.

Pindah ke Gradle Modular

Mari dapatkan proyek yang telah dibuat sebelumnya:

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

Setelah masuk ke direktori proyek terdahulu, mari ubah menjadi modular.

Buat direktori untuk menjadi sebuah submodul dan pindahkan berkas build.gradle dan seluruh kode sumber.

mkdir percuma-app
mv build.gradle src percuma-app

Ingat, build.gradle adalah seperti Makefile. Isinya adalah aturan yang diperlukan untuk mengompilasi.

Selanjutnya, beritahu percuma bahwa dia memiliki submodul percuma-app.

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

Terakhir, tambahkan modul percuma-app sebagai syarat yang dibutuhkan oleh percuma.

cat >> build.gradle << EOF
apply plugin: 'java'

dependencies {
  compile ':percuma-app'
}
EOF

Karena kita mau mengompilasi proyek ini, maka jangan lupa tambahkan plugin java pada aturan Gradle. Secara otomatis Gradle akan menjalankan perintah-perintah yang dijalankan pada proyek utama pada submodulnya nanti. Kalau tidak percaya, silakan saja coba:

./gradlew -q run

Hasilnya harusnya sama, sih.

Cara Membuat Proyek Gradle secara Manual yang Sebenarnya Bisa Dengan Mudah Dilakukan dengan “New Project” pada IntelliJ atau Eclipse

Cara Membuat Proyek Gradle secara Manual yang Sebenarnya Bisa Dengan Mudah Dilakukan dengan “New Project” pada IntelliJ atau Eclipse

Seperti judul blog ini, yang saya tuliskan ini adalah sesuatu yang sia-sia. Anda bisa langsung menggunakan aplikasi seperti IntelliJ atau Eclipse. Dengan penyunting itu, Anda tinggal membuat “New Project” dan semuanya sudah terkonfigurasi.

Tapi, mungkin Anda salah satu elitis yang lebih suka menggunakan terminal. Atau, Anda ingin tahu cara kerja Gradle sehingga Anda dapat setidaknya sedikit paham kalau ada masalah. Kalau saya, saya hanya sedang iseng sebelum menunggu waktunya tiba untuk menonton Warcraft di bioskop.

Proyek hanya Sejauh Direktori Kosong

Mari buat proyek baru. Caranya, buat direktori kosong dan dua buah berkas Gradle: build.gradle dan settings.gradle.

mkdir percuma && cd percuma
touch build.gradle settings.gradle

Mari namakan proyek kita ini “proyekPercuma”.

echo "rootProject.name = 'percuma'" >> settings.gradle

Secara umum, ini sudah siap. Tapi tunggu dulu, Kisanak! Kisanak tidak akan pernah lengkap ilmu bila tanpa jurus Monyet Membungkus Pisang!

Proyek hanya Sejauh Pembungkus

Java adalah sebuah pustaka yang sering kali berdiri sendiri. Hal ini karena sering kali distribusi menggunakan versi yang lawas. Bayangkan, Kisanak! Ini sudah 2016, namun Kubuntu Xenial (16.04) yang saya pakai masih menggunakan Gradle versi 2.10.

sudo apt-get install -y gradle && gradle -v

Hasilnya:

------------------------------------------------------------
Gradle 2.10
------------------------------------------------------------

Build time:   2016-01-26 15:17:49 UTC
Build number: none
Revision:     UNKNOWN

Groovy:       2.4.5
Ant:          Apache Ant(TM) version 1.9.6 compiled on July 8 2015
JVM:          1.8.0_91 (Oracle Corporation 25.91-b14)
OS:           Linux 4.4.0-22-generic amd64

Astaga! Padahal, versi terbaru sudah ada lama sebelum Xenial. Belum lagi, beberapa pustaka terbaru memanfaatkan Gradle versi terbaru.

Supaya kita menggunakan Gradle terbaru, mari buat skrip pembungkus Gradle. Saat penulisan Gradle terbaru versi 2.13.

gradle wrapper --gradle-version 2.13

Anda bisa lakukan ini untuk memperbaharui Gradle pada proyek yang lama ke versi yang terbaru. Sekarang lihat versinya:

$ ./gradlew -v

------------------------------------------------------------
Gradle 2.13
------------------------------------------------------------

Build time:   2016-04-25 04:10:10 UTC
Build number: none
Revision:     3b427b1481e46232107303c90be7b05079b05b1c

Groovy:       2.4.4
Ant:          Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM:          1.8.0_91 (Oracle Corporation 25.91-b14)
OS:           Linux 4.4.0-22-generic amd64

Selesai, deh.

Tunggu Dulu, Kisanak!

Mari buat sebuah proyek Java sederhana.

cat >> build.gradle << EOF
buildscript {
  repositories {
    jcenter()
  }
}

apply plugin: 'java'
apply plugin: 'application'
EOF

Lalu buat struktur direktori Java (kode sumber dan sumber daya):

mkdir -p src/main/java/ && mkdir -p src/main/resources

Sebagai pemrogram Java yang baik, seharusnya kita menaruh berkas Java pada paket-paket. Mari buat direktori paket Java.

mkdir -p src/main/java/aja/jp/percuma

Buat sebuah kelas sederhana.

cat > src/main/java/aja/jp/percuma/TestMain.java << EOF
package aja.jp.percuma;

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

Tambahkan berkas Java ini sebagai kelas utama dalam proyek percuma.

echo "mainClassName = 'aja.jp.percuma.TestMain'" >> build.gradle

Sekarang tinggal dicoba jalankan:

./gradlew -q run

Saya sengaja tambahkan “-q” agar keluaran dari Gradle tidak keluar. Sehingga, hasilnya langsung keluaran dari aplikasi, yakni:

Jun 08, 2016 5:20:53 PM aja.jp.percuma.TestMain main
INFO: Hello, world!

Kalau tanpa “-q” dia akan berisik seperti ini:

:compileJava
:processResources UP-TO-DATE
:classes
:run
Jun 08, 2016 5:23:40 PM aja.jp.percuma.TestMain main
INFO: Hello, world!

BUILD SUCCESSFUL

Total time: 8.079 secs

This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.13/userguide/gradle_daemon.html

Bersih-bersih

Kadang kalau proyek sudah besar dan kompleks, kita perlu membersihkan hasil kompilasi secara manual:

./gradlew clean

Mau buat distribusi supaya keren?

./gradlew installDist

Sehingga, kita jalankan dengan:

./build/install/percuma/bin/percuma

Ada .bat juga di situ untuk menjalankan di sistem terlarang.

Mau publikasikan hasil pekerjaan?

./gradlew distZip

Berkasnya ada di ./build/distributions/percuma.zip

Mau tahu perintah Gradle yang lain?

./gradlew tasks

Selebihnya terserah Anda. Gampang, ‘kan?

Bacaan Lebih Lanjut