Obat untuk Kode yang Sakit: KISS, DRY, SoC, YAGNI, SOLID
Hai gaess, pada posting sebelumnya kita membahas tentang kesehatan kode, juga tentang kode program yang “sakit”. Hmm, maksudnya apa ya? Buat yang penasaran, silakan baca dulu postingan ya.
Nah, pada kesempatan kali ini kita akan membahas “obat”-nya untuk kode-kode yang “sakit” tersebut. Apabila kita terapkan “obat” ini, insyaAllah kode kita akan menjadi “sehat wal ‘afiyat”. Aamiin..
“Obat” ini tidak lain merupakan prinsip-prinsip/aturan yang harus diikuti oleh para programmer. Apabila prinsip ini diterapkan maka kode yang dihasilkan akan lebih bersih, rapi, mudah dibaca, dan mudah di- maintain.
Mudah di- maintain artinya apabila terdapat bugs akan lebih mudah untuk di- debug. Apabila terdapat perubahan/penambahan kode (baca: perubahaan requirements), akan lebih cepat di-implementasikan dan lebih aman dari terjadinya error. Begitu juga apabila aplikasinya dikerjakan oleh banyak programmer, maka akan lebih mudah untuk berkolaborasi. Artinya kode tersebut dalam keadaan “fit” atau “sehat”.
KISS
Ok, kita mulai dari prinsip yang paling simple: KISS ( Keep It Simple, Stupid / Keep It Stupid Simple / Keep It Simple, Silly / Keep It Simple and Straightforward Keep It Small and Simple).
Dari namanya, kita pasti sudah bisa menebak maksudnya. Yup, prinsip ini mengajarkan kita agar jangan terlalu berfikir kompleks untuk masalah yang sederhana. Gunakan solusi yang sederhana untuk masalah yang sederhana.
Contoh: kita tidak perlu menggunakan microservices architecture untuk kebutuhan landing page sederhana. Contoh lain dalam kode:
NOT KISS
Di bawah contoh kode untuk mengecek plat nomor taksi, tapi caranya tidak KISS. Yang membaca kode ini mungkin tidak mengerti maksud pengecekan ini, karena ada logic yang cukup kompleks di situ.
if (substr($platNomor, -2, 1) == 'T' || substr($platNomor, -2, 2) == 'UA') {
// do something
}
KISS
Tapi dengan prinsip ini, kode yang kompleks tersebut akan di-extract dan diberi nama yang jelas, sehingga pada proses pengecekan menjadi lebih jelas dan simple.
if ($this->platNomorTaksi($platNomor)) {
// do something
}
function platNomorTaksi($platNomor) {
return substr($platNomor, -2, 1) == 'T' || substr($platNomor, -2, 2) == 'UA';
}
DRY
Don’t Repeat Yourself. Jangan membuat kode yang sama secara berulang-ulang di berbagai tempat. Ini akan membuat kode sulit untuk di- maintain. Cukup membuat satu fungsi di satu tempat lalu panggil/gunakan fungsi tersebut secara berulang-ulang.
DRY juga berlaku di level yang lebih tinggi, contoh pada class dan package. Jangan membuat membuat class yang sama fungsinya jika sudah ada class lain. Gunakan class tersebut atau inherit jika diperlukan modifikasi.
Kebalikan dari prinsip DRY adalah WET (Write Everything Twice). Dengan WET, kode yang sama ditulis berulang-ulang.
Kita langsung cek saja contoh-contoh nya.
Not DRY ~ WET
function showInvoice() {
$total = $this->price - $this->discount;
echo 'Total: ' . $total;
}
function sendInvoice() {
$total = $this->price - $this->discount;
$this->email('foo@bar.com', $total);
}
Pada contoh di atas, kode $this->price - $this->discount
ditulis berulang-ulang (WET). Jika ada perubahan perhitungan total, maka kode-nya harus dirubah satu-satu. Ini tidak efisien. Kode ini tidak sehat. "Obat" dari penyakit ini bisa dilihat dari contoh di bawah:
DRY
Kode yang berulang-ulang “dibungkus” di satu fungsi dan dipanggil dari berbagai tempat. Sehingga jika ada perubahan requirements perhitungan total, kita tinggal merubah di satu fungsi saja. Efisien. “Sehat”.
function showInvoice() {
echo 'Total ' . $this->countTotal();
}
function sendInvoice() {
$this->email('foo@bar.com', $this->countTotal());
}
function countTotal() {
return $this->price - $this->discount;
}
Contoh lain
WET
// Flow A
$user = getCurrentUser();
$firstName = $user->getFirstName();
$lastName = $user->getLastName();
echo “$firstName $lastName“;
// Flow B
$user = getCurrentUser();
$firstName = $user->getFirstName();
$lastName = $user->getLastName();
echo “$firstName $lastName“;
DRY
function getFullName($user) {
$firstName = $user->getFirstName();
$lastName = $user->getLastName();
return “$firstName $lastName”;
}
// Flow A
echo getFullName(getCurrentUser());
// Flow B
echo getFullName(getCurrentUser());
// Other Flows...
echo getFullName(getCurrentUser());
SoC
Separation of Concerns atau pemisahan concern (perhatian/fokus).
Maksudnya, apabila dalam satu function/class/package terdapat banyak concerns, sebaiknya dipecah lagi menjadi beberapa functions dengan satu concern di masing-masing function.
Contoh
Before SoC
function process($transaction) {
// concern: data access
$account = query(“select * from accounts where number = {$transaction->account_number}”);
// concern: bisnis
if ($account->status == ACCOUNT_STATUS_ACTIVE) {
$account->balance = $account->balance - $transaction->price;
}
// concern: tampilan
echo "<strong>{$account->name} berhasil membayar {$transaction->id}</strong>";
}
After SoC
function process($transaction) {
// dipisah ke class/modul tersendiri khusus concern masalah data access
$account = $this->accountDao->getByNumber($transaction->accountNumber);
// dipisah ke class/modul tersendiri khusus concern masalah bisnis
$this->billing->charge($account, $transaction);
// dipisah ke class/modul tersendiri khusus concern masalah tampilan
$this->view($account, $transaction);
}
YAGNI
You Ain’t (Aren’t) Gonna Need It = Kamu tidak akan membutuhkannya.
Prinsip ini mengajarkan agar kita menulis kode hanya yang diperlukan, jangan berfikir terlalu panjang sehingga memasukan fungsi-fungsi yang tidak akan kita perlukan.
Contoh sebagai programmer, kita diminta untuk membuat sebuah prototype aplikasi online store. Kita berfikir akan membuatnya dengan teknologi Flutter untuk mobile app nya, backend nya dengan Spring Boot dengan arsitektur microservices. DB nya menggunakan MongoDB dan Redis sebagai cache nya. Tapi ternyata setelah kita buat, product manager kita hanya meng-capture view-nya untuk ditampilkan di slide presentasi.
YAGNI sejalan dengan KISS yaitu kita jangan berfikir terlalu jauh dan kompleks. Berfikir ke depan bagus, tapi harus ada batasnya. Karena dalam pengerjaan project ada batas-batas yang harus kita ikuti, contoh timeline, budget, dsb.
SOLID
SOLID terdiri dari lima prinsip:
- SRP, Single Responsibility Principle
- OCP, Open Closed Principle
- LSP, Liskov Substitution Principle
- ISP, Interface Segregation Principle
- DIP, Dependency Inversion/Injention Principle
SOLID kayaknya memerlukan posting tersendiri mengingat item-nya cukup banyak dan kompleks. Intinya dengan SOLID, kita bisa membuat program lebih flexible, maintainable, extensible, scalable, dll.
Mudah-mudahan di lain kesempatan kita bisa membahas dengan lebih detail prinsip-prinsip SOLID ini.
Update: Posting tentang SOLID bisa dilihat di sini ya.
Kesimpulan
Untuk membuat kode program yang bersih dan sehat diperlukan teknik dan prinsip-prinsip tertentu yang harus diterapkan oleh programmer. Apabila prinsip-prinsip ini diterapkan, maka kode akan menjadi lebih “sehat” dan “panjang umur”, artinya mudah di- maintain dan dikembangkan.
Sebaliknya, kode yang tidak mengikuti prinsip-prinsip tersebut akan lebih mudah error, sulit di- maintain, sulit dikembangkan. Istilah lainnya kode tersebut “tidak sehat” alias “sakit”.
Sebetulnya selain prinsip-prinsip di atas masih banyak prinsip dan teknik lain yang dapat digunakan untuk membuat kode menjadi lebih bersih dan sehat. InsyaAllah di kesempatan lain kita akan membahas teknik-teknik lainnya.. So, Stay cun gaess.. Jangan lupa clap dan comment nya ya…
Akhir kata, mudah-mudahan posting ini bermanfaat khususnya buat penulis umumnya buat pembaca semua.
Wassalam.