KISS (Keep It Simple, Stupid) artinya pilih solusi paling sederhana yang benar. Kode yang "pintar" bikin penulisnya bangga, kode yang sederhana bikin pembacanya cepat paham. Bayangin petunjuk jalan ke rumahmu. "Dari masjid belok kiri, rumah ketiga yang catnya hijau" lebih berguna daripada koordinat GPS sampai delapan angka di belakang koma. Dua-duanya benar, tapi cuma satu yang bisa diikuti tanpa alat.
🧪 Tebakan cepat: di versi pintar di bawah ada potongan
(t < 2e5) * 15e3. Kalautbernilai 189000, hasilnya berapa? Tebak dulu, jawabannya ada di bagian "Membaca versi pintar".
Versi pintar dan versi biasa
Dua cara menulis kasir Toko Kaos Raka. Versi pintar, dua baris:
const calculateTotal = (c, v) =>
'Total: Rp ' + (t => t + (t < 2e5) * 15e3)(c.reduce((s, i) => s + i.price * i.qty, 0) * (v === 'HEMAT10' ? 0.9 : 1)).toLocaleString('id-ID');
Versi biasa, dengan loop:
const VOUCHER_DISCOUNT = 0.1;
const FREE_SHIPPING_MIN = 200000;
const SHIPPING_FEE = 15000;
function calculateTotal(cart, voucherCode) {
let total = 0;
for (const item of cart) {
total += item.price * item.qty;
}
if (voucherCode === 'HEMAT10') total -= total * VOUCHER_DISCOUNT;
if (total < FREE_SHIPPING_MIN) total += SHIPPING_FEE;
return 'Total: Rp ' + total.toLocaleString('id-ID');
}
Dijalankan dengan empat keranjang dari lesson pertama, hasilnya sama persis:
| Keranjang | Versi pintar | Versi biasa |
|---|---|---|
A + HEMAT10 |
Total: Rp 220.500 |
Total: Rp 220.500 |
| A tanpa voucher | Total: Rp 245.000 |
Total: Rp 245.000 |
| C tanpa voucher | Total: Rp 90.000 |
Total: Rp 90.000 |
D + HEMAT10 |
Total: Rp 204.000 |
Total: Rp 204.000 |
Jadi bedanya bukan di hasil, tapi di berapa trik yang harus dipahami pembaca.
Membaca versi pintar
Untuk membaca satu baris itu, kamu harus tahu lima hal:
(t => ...)(...): fungsi panah yang langsung dipanggil, supaya hasil hitungan bisa diberi namat.2e5itu 200000 dan15e3itu 15000 (notasi eksponen: 2 × 10⁵).(t < 2e5) * 15e3: boolean dikali angka.truedihitung 1 danfalsedihitung 0, jadi hasilnya 15000 atau 0.* 0.9: potongan 10% ditulis terbalik, sebagai "bayar 90%".reduce((s, i) => ...): menjumlahkan, dengan nama satu huruf.
Dengan t = 189000, 189000 < 200000 itu true, dan true * 15000 = 15000. Itu jawaban tebakannya: ongkir ditambahkan. Versi biasa cuma butuh for...of dan if, dibaca dari atas ke bawah.
Bedanya terasa saat mencari bug
Pembeli dengan keranjang D bertanya kenapa dia bayar ongkir. Di versi biasa, kamu tinggal menaruh console.log di antara langkah:
console.log('subtotal:', total); // subtotal: 210000
if (voucherCode === 'HEMAT10') total -= total * VOUCHER_DISCOUNT;
console.log('setelah voucher:', total); // setelah voucher: 189000
if (total < FREE_SHIPPING_MIN) total += SHIPPING_FEE;
console.log('setelah ongkir:', total); // setelah ongkir: 204000
Jawabannya langsung terbaca: setelah potongan, totalnya 189.000, di bawah batas 200.000. Di versi pintar gak ada tempat untuk console.log di antara langkahnya. Kamu harus menulis ulang dulu jadi versi biasa. Kode yang susah dipahami juga susah dites dan di-debug, dan itu memperlambat semua perubahan berikutnya.
Kebanyakan jaga-jaga juga bukan sederhana
Kebalikan dari versi pintar adalah versi yang menjaga semua kemungkinan. Contohnya dari latihan:
function isAdult(age) {
try {
if (age !== null && age !== undefined) {
if (typeof age === 'number') {
if (age >= 18) {
return true;
} else {
return false;
}
} else {
return false;
}
} else {
return false;
}
} catch (e) {
return false;
}
}
Semua ini cuma menjawab satu pertanyaan, dan jawabannya sudah berupa true atau false:
function isAdult(age) {
return age >= 18;
}
if (x) { return true; } else { return false; }sama denganreturn x;.try/catchdi sekitar perbandingan gak menangkap apa-apa, karenaage >= 18gak pernah melempar error.- Untuk angka hasilnya sama persis:
isAdult(18)true,isAdult(17)false,isAdult(0)false,isAdult(65)true.nulldanundefinedjuga tetapfalse. - Satu beda:
isAdult('20'). Versi lamafalsekarena cektypeof, versi barutruekarena'20' >= 18mengubah teksnya jadi angka. Kalau umur bisa datang sebagai teks dari form, tulisreturn typeof age === 'number' && age >= 18;, tetap satu baris. Refactor harus menjaga hasil untuk input yang benar-benar masuk.
Hal yang sama berlaku untuk class dan pola desain yang dipasang "siapa tahu nanti perlu", misalnya VoucherFactory dan DiscountStrategy untuk satu voucher HEMAT10. Prinsip pelengkapnya disebut YAGNI (You Aren't Gonna Need It): tambahkan abstraksi saat kebutuhannya sudah ada, misalnya saat ada puluhan voucher dengan aturan berbeda.
Latihan: isAdult
Sederhanakan isAdult(age) jadi satu ekspresi boolean. Yang dinilai: tiga baris output tetap true, false, true (untuk 20, 17, 18), isAdult(18) true, isAdult(17) false, isAdult(0) false, isAdult(65) true, dan gak ada lagi try { atau else if (. Nama fungsi tetap isAdult dan parameternya tetap age.
⚠️ Jebakan yang sering ketemu
- Mengira satu baris berarti sederhana. Versi pintar cuma dua baris, tapi butuh lima trik. Ukurannya berapa hal yang harus dipahami pembaca, bukan jumlah baris.
ifyang mengembalikantrueataufalse. Kembalikan kondisinya langsung:return age >= 18;.try/catchyang menelan semua error. Kalau isinya gak bisa error, hapus. Kalau bisa, menelannya diam-diam menyembunyikan bug.- Menghapus jaga-jaga yang ternyata dibutuhkan. Cek dulu input apa yang benar-benar masuk. Kalau teks bisa masuk, pertahankan cek
typeofdalam satu baris. - Abstraksi untuk masa depan yang belum datang. Class, factory dan config untuk satu kasus menambah hal yang harus dipahami tanpa memberi apa-apa sekarang.
TL;DR: KISS artinya solusi paling sederhana yang benar. Versi pintar kasir ((t < 2e5) * 15e3, * 0.9, fungsi panah yang langsung dipanggil) dan versi biasa dengan loop memberi hasil yang sama di keempat keranjang, tapi versi pintar butuh lima trik untuk dibaca dan gak bisa diberi console.log di antara langkahnya. Kebanyakan jaga-jaga juga bukan sederhana: isAdult dengan try, if bersarang dan return true/false cukup jadi return age >= 18;, dengan hasil sama untuk angka (18 true, 17 false, 0 false, 65 true). Over-engineering bikin kode lebih sulit dipahami, dites dan di-debug, jadi pengembangan melambat. Tambahkan abstraksi saat dibutuhkan (YAGNI), dan pastikan refactor tetap memberi hasil yang sama untuk input yang benar-benar masuk.