Ilustrasi blok kode berantakan berubah menjadi blok kode rapi dengan panah di antaranya

Selama 17 episode kita belajar meminta AI menulis kode. Sekarang saatnya jujur soal satu hal. Kode yang keluar dari AI itu ibarat mie instan. Cepat jadi, langsung bisa dimakan, tapi kalau disajikan apa adanya ke pelanggan, restoranmu tidak akan bertahan lama. Di episode 18 ini kita belajar tahap yang memisahkan vibe coder iseng dari vibe coder profesional, yaitu refactoring: mengubah kode mentah hasil AI menjadi kode yang siap produksi.

Kenapa ini penting? Karena hampir semua kode AI lahir dengan masalah yang sama. Ia ditulis untuk memuaskan prompt-mu, bukan untuk dibaca manusia enam bulan kemudian. Kalau aplikasimu kecil dan sekali pakai, masalahnya tidak terasa. Tapi begitu kode itu dipakai orang lain, dipakai berulang, atau perlu diubah, tagihannya datang. Kabar baiknya, refactoring adalah keterampilan yang justru paling enak dikerjakan bareng AI, karena kamu tinggal menyuruh si pembuat berantakan itu membereskan karyanya sendiri.

Ciri Khas Kode Mentah Hasil AI

Sebelum membereskan, kamu harus bisa mengenali kekacauan. Berikut empat ciri yang hampir selalu muncul di kode mentah hasil AI.

Pertama, fungsi raksasa. AI suka memasukkan semua logika ke satu fungsi sepanjang 80 sampai 150 baris. Baca satu fungsi saja kamu harus mengingat sepuluh hal sekaligus di kepala. Fungsi sehat idealnya melakukan satu hal dan panjangnya bisa dibaca dalam sekali pandang, kira-kira di bawah 30 baris.

Kedua, nama yang asal jadi. Variabel bernama data, temp, result2, atau fungsi bernama processData. Nama seperti itu tidak bercerita. Pembaca harus menebak isinya dengan membaca seluruh badan fungsi. Nama yang baik itu seperti label toples dapur. Kamu tahu isinya tanpa membuka tutupnya.

Ketiga, error handling yang minim. Kode AI biasanya ditulis untuk skenario bahagia. Input selalu benar, koneksi selalu lancar, file selalu ada. Di dunia nyata, pengguna mengetik huruf di kolom angka, internet putus di tengah jalan, dan file yang dicari ternyata sudah dihapus. Kode tanpa penanganan error akan meledak di momen paling memalukan, yaitu saat dipakai orang lain.

Keempat, duplikasi. AI tidak ingat bahwa tiga prompt lalu ia sudah menulis logika yang sama. Hasilnya, potongan kode yang nyaris identik tersebar di lima tempat berbeda. Nanti saat aturannya berubah, kamu harus ingat mengubah kelimanya, dan satu saja yang lupa akan jadi bug misterius.

Berhenti dan tebak dulu! Dari empat ciri di atas, mana yang paling berbahaya kalau aplikasimu sudah dipakai banyak orang?

Jawaban: error handling yang minim. Fungsi raksasa dan nama asal bikin pusing kamu sebagai developer, tapi error handling yang minim bikin menderita penggunamu. Aplikasi yang crash tanpa pesan jelas akan membuat orang kehilangan kepercayaan, dan kepercayaan jauh lebih mahal daripada waktu refactoring. Karena itu, saat waktu refactoring terbatas, dahulukan error handling.

Langkah 1 dan 2: Pecah Fungsi, Beri Nama Jelas

Refactoring selalu mulai dari struktur. Ambil fungsi raksasa, kenali blok-blok logika di dalamnya, lalu pecah menjadi fungsi-fungsi kecil yang masing-masing punya satu tanggung jawab. Setiap fungsi kecil diberi nama yang menjelaskan apa yang dilakukannya, bukan bagaimana caranya. Contoh, fungsi processData() yang isinya validasi, hitung total, simpan ke database, dan kirim email, dipecah menjadi validasiPesanan(), hitungTotal(), simpanPesanan(), dan kirimEmailKonfirmasi().

Aturan praktisnya sederhana. Kalau kamu kesulitan memberi nama sebuah fungsi dalam tiga kata, kemungkinan fungsi itu masih mengerjakan dua hal sekaligus dan perlu dipecah lagi. Nama yang baik membuat komentar menjadi tidak perlu, karena kodenya sudah bercerita sendiri. Ini langkah yang dampaknya paling terasa saat kamu membaca ulang kodemu sendiri tiga bulan kemudian.

Langkah 3 dan 4: Error Handling dan Dokumentasi

Setelah struktur rapi, tutup lubang-lubangnya. Untuk setiap fungsi, tanyakan tiga hal. Apa yang terjadi kalau inputnya kosong? Apa yang terjadi kalau inputnya salah format? Apa yang terjadi kalau layanan luar (database, API, file) gagal? Tambahkan pemeriksaan di awal fungsi dan tangani kegagalan dengan pesan error yang jelas, bukan sekadar crash diam-diam.

Terakhir, tulis dokumentasi secukupnya. Bukan esai, cukup tiga baris di atas setiap fungsi penting. Apa yang dilakukan fungsi ini, apa parameter yang diterimanya, dan apa yang dikembalikannya. AI sangat pandai menulis dokumentasi semacam ini, jadi jangan kerjakan manual. Dokumentasi yang baik membuat fungsi kecilmu bisa dipakai ulang tanpa harus membaca isinya.

Contoh Sebelum dan Sesudah

Lihat contoh nyata di bawah ini. Fungsi pertama adalah gaya mentah khas AI untuk menghitung total belanja. Fungsi kedua adalah hasil refactoringnya. Perhatikan bedanya.

// SEBELUM: kode mentah hasil AI
function processData(d) {
  let t = 0;
  for (let i = 0; i < d.length; i++) {
    t += d[i].p * d[i].q;
  }
  let disc = 0;
  if (t > 100000) disc = t * 0.1;
  return t - disc;
}
// SESUDAH: production-ready
// Menghitung total belanja setelah diskon.
// items: array {harga, jumlah}. Mengembalikan angka total dalam rupiah.
function hitungTotalBelanja(items) {
  if (!Array.isArray(items) || items.length === 0) {
    throw new Error('Daftar belanja tidak boleh kosong.');
  }
  const subtotal = jumlahkanSubtotal(items);
  const diskon = hitungDiskon(subtotal);
  return subtotal - diskon;
}

function jumlahkanSubtotal(items) {
  return items.reduce((total, item) => {
    validasiItem(item);
    return total + item.harga * item.jumlah;
  }, 0);
}

function validasiItem(item) {
  if (typeof item.harga !== 'number' || item.harga <= 0) {
    throw new Error('Harga barang harus angka positif.');
  }
  if (!Number.isInteger(item.jumlah) || item.jumlah <= 0) {
    throw new Error('Jumlah barang harus bilangan bulat positif.');
  }
}

function hitungDiskon(subtotal) {
  const BATAS_DISKON = 100000;
  const PERSEN_DISKON = 0.1;
  return subtotal > BATAS_DISKON ? subtotal * PERSEN_DISKON : 0;
}

Perhatikan apa yang berubah. Nama processData menjadi hitungTotalBelanja yang langsung menjelaskan isinya. Variabel misterius d, t, disc hilang. Angka ajaib 100000 dan 0.1 diberi nama konstanta. Validasi input ditambahkan di awal. Dan setiap fungsi hanya mengerjakan satu hal. Panjang kodenya bertambah, tapi biaya membacanya justru turun drastis.

Cara Aman Minta AI Me-refactor Kodenya Sendiri

Bagian paling menyenangkannya, kamu tidak perlu refactoring manual. Tapi ada caranya supaya AI tidak malah merusak kode yang sudah jalan. Ikuti urutan ini.

Pertama, kunci perilaku dengan test. Sebelum menyentuh apa pun, minta AI membuat test sederhana yang membuktikan fungsi lamamu bekerja untuk beberapa kasus, termasuk kasus normal dan kasus aneh. Test ini adalah jaring pengaman. Kalau hasil refactor lolos semua test, perilakunya tidak berubah.

Kedua, refactor satu file dalam satu waktu. Jangan suruh AI me-refactor seluruh proyek sekaligus. Pilih satu fungsi atau satu file, selesaikan, pastikan test lolos, baru lanjut ke berikutnya. Perubahan kecil yang terverifikasi selalu lebih aman daripada perubahan besar yang penuh harapan.

Ketiga, beri instruksi yang spesifik. Prompt samar seperti "rapikan kode ini" menghasilkan rapian yang samar juga. Sebutkan empat langkah yang kita bahas: pecah fungsi maksimal 30 baris, beri nama deskriptif berbahasa Indonesia atau Inggris yang konsisten, tambah validasi input, tulis dokumentasi tiga baris. Contoh prompt siap pakainya ada di bawah.

Refactor fungsi di file ini TANPA mengubah perilakunya.
Aturan:
1. Pecah fungsi yang lebih dari 30 baris menjadi fungsi-fungsi kecil,
   masing-masing satu tanggung jawab.
2. Ganti semua nama variabel dan fungsi yang ambigu (data, temp, result2,
   processData) dengan nama deskriptif yang konsisten.
3. Tambahkan validasi input di awal setiap fungsi publik, dengan pesan
   error berbahasa Indonesia yang jelas.
4. Tulis dokumentasi 3 baris di atas setiap fungsi: apa yang dilakukan,
   parameter apa yang diterima, apa yang dikembalikan.
5. Jangan ubah logika bisnis. Setelah selesai, jalankan ulang test
   yang sudah ada dan pastikan semuanya lolos.

Kuis: Sebelum meminta AI me-refactor kode, langkah pengaman pertama yang wajib dilakukan adalah...

Jebakan Umum Saat Refactoring

Ada tiga jebakan yang sering menjerat pemula. Pertama, refactor sambil menambah fitur. Ini resep bencana. Refactoring artinya mengubah struktur tanpa mengubah perilaku. Kalau perilakunya ikut berubah, kamu tidak akan tahu apakah bug berasal dari struktur baru atau fitur baru. Satu waktu, satu jenis perubahan.

Kedua, over-refactoring. Tidak semua kode perlu disempurnakan. Kode yang hanya dipakai sekali setahun dan sudah stabil tidak butuh dipecah jadi sepuluh fungsi. Refactor bagian yang sering berubah dan sering dibaca. Waktu dan kuota AI-mu terbatas, pakai untuk yang berdampak.

Ketiga, percaya buta pada hasil AI. AI kadang mengubah perilaku secara halus saat refactor, misalnya mengubah urutan operasi atau membulatkan angka secara berbeda. Itulah kenapa test di langkah pertama tadi tidak bisa ditawar. Tidak ada test, tidak ada refactor.

Latihan Minggu Ini

Ambil satu proyek lamamu, proyek apa pun yang kodenya ditulis bareng AI. Langkah satu, pilih satu fungsi terpanjang di proyek itu dan catat berapa baris panjangnya. Langkah dua, minta AI membuatkan test untuk fungsi tersebut sampai semua test lolos. Langkah tiga, salin prompt refactor dari artikel ini, tempel, dan biarkan AI bekerja. Langkah empat, jalankan ulang test dan bandingkan. Kode barunya lebih panjang atau lebih pendek? Lebih mudah dibaca? Catat jawabanmu. Pengalaman sekali melakukan ini lebih berharga daripada sepuluh artikel tentang refactoring.

Di episode 19 kita masuk ke bagian paling seru dari seri ini, "Studi Kasus SaaS dari Nol (1): Ide dan Arsitektur". Semua teknik dari episode 1 sampai 18 akan kita pakai untuk merancang aplikasi kasir online sungguhan untuk UMKM. Dari teori ke medan perang. Sampai jumpa besok jam 21:00. Bakar semangat kodingmu seperti api kompor.