Clean code adalah kode yang gampang dibaca dan aman diubah oleh orang lain, termasuk kamu sendiri enam bulan lagi. Bayangin titipan belanja dari ibu: "gl 2, tlr 10, mny 1". Yang nulis paham. Kamu di depan rak harus nebak: gula 2 kilo? telur 10 butir? minyak 1 liter? Kode juga begitu. Komputer gak peduli variabelnya bernama k atau cart, tapi manusia yang membacanya harus menebak tiap singkatan.
🧪 Tebakan cepat: fungsi kasir yang berantakan dan versi bersihnya dijalankan dengan keranjang yang sama. Hasilnya sama, atau versi bersih lebih tepat? Tebak dulu, jawabannya ada di bagian "Komputer gak peduli, manusia peduli".
Contoh sepanjang track: kasir Toko Kaos Raka
Raka jualan kaos online. Aturan tokonya cuma dua:
- voucher
HEMAT10memotong 10% dari total belanja; - ongkir Rp 15.000, gratis kalau total setelah potongan minimal Rp 200.000.
Ini fungsi kasir yang ditulis buru-buru. Kodenya jalan dan hasilnya benar:
function hitung(k, v) {
let t = 0;
for (let i = 0; i < k.length; i++) {
t = t + k[i].price * k[i].qty;
}
if (v === 'HEMAT10') t = t - t * 0.1;
if (t < 200000) t = t + 15000;
return 'Total: Rp ' + t.toLocaleString('id-ID');
}
const cart = [
{ name: 'Kaos Polos Hitam', price: 75000, qty: 2 },
{ name: 'Kaos Sablon Kopi', price: 95000, qty: 1 },
];
console.log(hitung(cart, 'HEMAT10')); // Total: Rp 220.500
Sekarang jadi orang yang baru pertama membacanya. Sebelum berani mengubah satu baris, kamu harus menjawab enam pertanyaan:
kitu apa? Keranjang belanja, isinya barang denganpricedanqty.vitu apa? Kode voucher.titu apa? Total yang terus diperbarui.0.1itu apa? Potongan voucher 10%.200000itu batas apa? Batas gratis ongkir.15000itu apa? Ongkirnya.
Jawabannya cuma ada di kepala penulisnya. Angka tanpa penjelasan seperti 0.1 dan 200000 disebut magic number (angka ajaib).
Versi bersihnya
const VOUCHER_DISCOUNT = 0.1; // HEMAT10: potongan 10%
const FREE_SHIPPING_MIN = 200000; // gratis ongkir mulai Rp 200.000
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');
}
calculateTotal,cart,voucherCodedantotalmenjawab pertanyaan 1 sampai 3 lewat namanya.VOUCHER_DISCOUNT,FREE_SHIPPING_MINdanSHIPPING_FEEmemberi nama ke tiga magic number. Pertanyaan 4 sampai 6 terjawab.for (const item of cart)dibaca "untuk tiap item di cart", tanpa indexi.
Logikanya gak berubah sama sekali: urutan langkahnya sama, angkanya sama.
Komputer gak peduli, manusia peduli
Jalankan dua-duanya dengan keranjang yang sama:
> hitung(cart, 'HEMAT10')
Total: Rp 220.500
> calculateTotal(cart, 'HEMAT10')
Total: Rp 220.500
Sama persis. Itu jawaban tebakannya: merapikan kode gak bikin hasilnya lebih tepat. Yang berubah cuma seberapa cepat manusia paham dan seberapa aman kodenya diubah. Hitungannya: 2 × 75.000 + 95.000 = 245.000, dipotong 10% jadi 220.500, dan itu di atas 200.000 jadi gratis ongkir.
Mengubah bentuk kode tanpa mengubah hasilnya disebut refactor. Seluruh track ini adalah refactor kecil-kecilan atas fungsi kasir ini.
Kode lebih sering dibaca daripada ditulis
Fungsi kasir ditulis sekali, tapi dibaca tiap kali ada yang mau menambah voucher, mengubah ongkir, atau mencari bug. Robert C. Martin di buku Clean Code (2008) memperkirakan perbandingan waktu membaca dan menulis kode "well over 10 to 1", jauh di atas 10 banding 1. Itu perkiraan dari pengalamannya, bukan hasil pengukuran, tapi arahnya cocok dengan pengalaman banyak tim. Jadi biaya merawat kode (maintenance) sebagian besar adalah biaya membaca, dan kode yang gampang dibaca menurunkan biaya itu.
Technical debt: utang yang berbunga
Technical debt (utang teknis) adalah istilah dari Ward Cunningham (1992). Memilih jalan pintas daripada solusi yang benar itu seperti berutang: kamu dapat waktu sekarang, lalu bayar "bunga" tiap kali kodenya harus diubah, berupa waktu membaca yang lebih lama dan kesalahan yang lebih gampang terjadi.
Contoh: Raka minta "gratis ongkir mulai Rp 250.000". Di versi bersih kamu ubah satu konstanta, FREE_SHIPPING_MIN = 250000. Di versi berantakan kamu harus memastikan dulu bahwa 200000 itu batas ongkir. Makin banyak fitur ditempel ke hitung, makin besar bunganya.
Refactor yang mengubah hasil itu bug
Merapikan boleh, mengubah hasil gak. Cara paling murah untuk memastikannya: test kecil yang membandingkan hasil dengan yang seharusnya. Misalnya ada yang "merapikan" dengan memindah cek ongkir ke atas cek voucher:
function check(actual, expected) {
console.log(actual === expected ? 'OK ' + actual : 'BEDA ' + actual + ', harusnya ' + expected);
}
const cartD = [
{ name: 'Kaos Polos Hitam', price: 75000, qty: 1 },
{ name: 'Kaos Sablon Kopi', price: 95000, qty: 1 },
{ name: 'Topi Raka', price: 40000, qty: 1 },
];
check(calculateTotal(cart, 'HEMAT10'), 'Total: Rp 220.500');
check(calculateTotal(cartD, 'HEMAT10'), 'Total: Rp 204.000');
OK Total: Rp 220.500
BEDA Total: Rp 189.000, harusnya Total: Rp 204.000
Keranjang D belanjanya Rp 210.000. Urutan yang benar: dipotong dulu jadi 189.000, itu di bawah 200.000, jadi kena ongkir: 204.000. Kalau ongkir dicek duluan, 210.000 dianggap gratis ongkir. Keranjang pertama lolos dua-duanya, jadi tanpa keranjang D bug ini gak ketahuan.
📌 Peta track ini
Fungsi kasir ini akan dirapikan terus: nama yang jelas (Penamaan yang Baik), dipecah jadi fungsi kecil (Fungsi Kecil & Fokus), pemformat rupiah yang cukup ditulis sekali (DRY), versi pintar vs versi biasa (KISS), lalu tanggung jawab, error handling, komentar, dan teknik refactoring. Test kecil check ikut di tiap langkah.
⚠️ Jebakan yang sering ketemu
- Mengira clean code bikin program lebih cepat. Engine JavaScript gak peduli nama variabel:
tdantotaljalan sama cepat. Yang dihemat adalah waktu manusia. - Merapikan tanpa test. Tanpa membandingkan hasil sebelum dan sesudah, kamu gak tahu apakah refactor-mu mengubah perilaku. Fungsi kecil seperti
checksudah cukup untuk mulai. - Merapikan semuanya sekaligus. Rapikan bagian yang mau kamu ubah, sedikit demi sedikit, dan jalankan test tiap langkah.
- Mengira nama yang bagus menggantikan dokumentasi. Nama menjelaskan apa. Alasan bisnis, misalnya kenapa batasnya 200.000, kadang tetap perlu ditulis.
- "Aku kerja sendiri, gak perlu rapi." Kamu enam bulan lagi adalah pembaca baru yang sudah lupa konteksnya.
TL;DR: Clean code adalah kode yang gampang dibaca dan aman diubah manusia. Komputer gak peduli: hitung(k, v) dan calculateTotal(cart, voucherCode) sama-sama mencetak Total: Rp 220.500. Kode jauh lebih sering dibaca daripada ditulis, jadi nama yang jelas dan magic number yang diberi nama menurunkan biaya maintenance. Jalan pintas yang bikin kode susah dibaca adalah technical debt: bunganya dibayar tiap kali kode diubah. Refactor mengubah bentuk, bukan hasil. Test kecil yang membandingkan hasil sebelum dan sesudah, dengan keranjang yang tepat di batas aturan, menangkap refactor yang kebablasan.