Semua alat pada Section ini — debugger, logging, static analysis, formatter, refactoring — bekerja atas kode yang sudah ditulis. Code review bekerja atas manusianya: momen ketika dua pasang mata atau lebih memeriksa perubahan sebelum menyatu ke basis kode bersama. Dilakukan dengan benar, review adalah jaring pengaman kualitas sekaligus mekanisme penyebaran pengetahuan: bug tertangkap sebelum merugikan, dan konvensi arsitektur mengalir antar anggota. Dilakukan dengan buruk, review menjadi hambatan yang ditakuti: komentar memerintah tanpa alasan, diskusi selera tak berujung, dan persetujuan diberikan tanpa membaca. Pada Chapter penutup ini kita akan menyusun praktik review yang terukur dan berbudaya sehat.

Tujuan Review: Kualitas dan Pengetahuan #

Dua tujuan tersebut menentukan desain proses. Untuk kualitas, reviewer mencari hal yang paling mungkin luput dari penulisnya: kondisi batas, penanganan error, dan pelanggaran konvensi tim. Untuk pengetahuan, review memastikan tidak ada bagian basis kode yang hanya dipahami satu orang: reviewer yang membaca perubahan modul pembayaran hari ini siap membetulkannya saat insiden tengah malam nanti.

Konsekuensi desainnya: review yang sehat menuntut kehadiran reviewer yang sungguh membaca. Persetujuan dalam satu menit tanpa komentar bukan tanda kualitas tinggi, melainkan sinyal proses yang tidak dipercaya.

Ukuran Pull Request #

Satu angka mengubah segalanya: review pada PR kecil lebih dalam, lebih cepat, dan lebih hangat. Riset internal di tim besar secara konsisten menunjukkan pola yang sama — makin besar perubahan, makin dangkal pemeriksaannya. Ukuran yang nyaman bagi kebanyakan reviewer berada pada kisaran ratusan baris berubah; melampaui itu, kapasitas membaca menurun dan bug lolos.

Praktik yang menjaga ukuran tetap kecil:

  • Satu PR satu maksud — satu fitur, satu perbaikan, atau satu refactoring; jangan mencampur ketiganya.
  • Pisahkan perubahan mekanis dari perubahan logis — formatisasi dan rename massal dikirim sebagai PR sendiri yang mudah disetujui cepat.
  • Sebut konteks di deskripsi PR — masalah yang diselesaikan, cara mengujinya, dan tangkapan layar bila mengubah tampilan; reviewer tidak boleh menebak maksud.

Checklist Empat Pertanyaan #

Fokus review menjadi mudah dijalankan bila dijadikan checklist. Empat pertanyaan berikut menutup hampir seluruh kebutuhan:

  1. Benar? — logika menyelesaikan masalahnya; kondisi batas (nilai kosong, nol, maksimum) ditangani.
  2. Jelas? — nama deskriptif, method tidak terlalu panjang, pembaca baru dapat mengikuti alurnya.
  3. Aman? — input eksternal divalidasi, data sensitif tidak dicatat ke log, sumber daya ditutup.
  4. Teruji? — ada test untuk perilaku baru; test gagal bila kode kembali salah.

Checklist ini juga menetapkan batas wewenang reviewer: pertanyaan selera pribadi (tab vs spasi) bukan materi review — itu wilayah formatter dan Checkstyle sebagaimana dibahas pada Chapter sebelumnya.

Komentar adalah instrumen review yang paling menentukan budaya. Prinsip pertama: bertanya, bukan memerintah. “Mengapa validasi hanya terjadi di sini?” mengundang penulis menjelaskan konteks — dan penulis sering menemukan sendiri masalahnya saat menjawab; “Ubah ini” menutup ruang itu. Prinsip kedua: sertakan alasan — komentar dengan dasar penalaran dapat didiskusikan, komentar tanpa dasar hanya dapat dipatuhi atau ditolak. Prinsip ketiga, yang sering disebut aturan n+1: sisipkan apresiasi yang spesifik — satu komentar menghargai keputusan baik di samping n komentar perbaikan, menjaga motivasi dan menandai pola yang layak ditiru.

text
Komentar yang menghambat:
  "Ini salah."
  "Ubah."
  "Jangan begitu."
  "Kenapa tidak pakai cara saya?"

Komentar yang membangun:
  "Mengapa validasi hanya di method ini? Apakah pemanggil lain bisa melewatinya?"
  "Bagaimana kalau stok berubah di antara pemeriksaan dan pemotongan?"
  "Terima kasih sudah mengekstrak method ini — alur utama jauh lebih terbaca."

Perhatikan pola pada kolom kanan: pertanyaan terbuka mengarah ke diskusi, dan apresiasi menyebut hal spesifik yang dipuji — bukan pujian kosong.

Analisis Komentar Mini #

Untuk melihat komposisi komentar secara objektif, program kecil berikut mengklasifikasikan lima komentar review dengan heuristik awalan dan penanda alasan:

import java.util.ArrayList;
import java.util.List;

public class AnalisisKomentar {

    // Komentar review beku; klasifikasi berbasis awalan dan kata kunci sederhana
    static final List<String> KOMENTAR = List.of(
            "Mengapa validasi umur hanya terjadi di method ini?",
            "Bagaimana kalau input bernilai null saat panggilan pertama?",
            "Ubah nama variabel tmp menjadi totalHarga agar maksudnya terbaca.",
            "Jangan pakai System.out.println di kode produksi karena level tidak bisa disaring.",
            "Bagus, penanganan error di sini sudah rapi dan teruji."
    );

    public static void main(String[] args) {
        List<String> rincian = new ArrayList<>();
        int pertanyaan = 0;
        int perintah = 0;
        int apresiasi = 0;
        int denganAlasan = 0;

        for (String komentar : KOMENTAR) {
            String jenis;
            if (komentar.startsWith("Mengapa") || komentar.startsWith("Bagaimana kalau")) {
                jenis = "pertanyaan";
                pertanyaan++;
            } else if (komentar.startsWith("Ubah") || komentar.startsWith("Jangan")) {
                jenis = "perintah";
                perintah++;
            } else {
                jenis = "apresiasi";
                apresiasi++;
            }
            if (komentar.contains("karena") || komentar.contains("agar")) {
                denganAlasan++;
            }
            rincian.add("[" + jenis + "] " + komentar);
        }

        for (String r : rincian) {
            System.out.println(r);
        }

        System.out.println();
        System.out.println("Pertanyaan  : " + pertanyaan);
        System.out.println("Perintah    : " + perintah);
        System.out.println("Apresiasi   : " + apresiasi);
        System.out.println("Dengan alasan: " + denganAlasan + " dari " + KOMENTAR.size()
                + " komentar");
    }
}

Output yang Dihasilkan:

text
[pertanyaan] Mengapa validasi umur hanya terjadi di method ini?
[pertanyaan] Bagaimana kalau input bernilai null saat panggilan pertama?
[perintah] Ubah nama variabel tmp menjadi totalHarga agar maksudnya terbaca.
[perintah] Jangan pakai System.out.println di kode produksi karena level tidak bisa disaring.
[apresiasi] Bagus, penanganan error di sini sudah rapi dan teruji.

Pertanyaan  : 2
Perintah    : 2
Apresiasi   : 1
Dengan alasan: 2 dari 5 komentar

Mari kita bedah klasifikasi tersebut:

  1. Deteksi pertanyaan (startsWith("Mengapa") dan "Bagaimana kalau"): dua komentar pembuka terklasifikasi sebagai pertanyaan — bentuk yang membuka dialog antara reviewer dan penulis.
  2. Deteksi perintah ("Ubah" dan "Jangan"): dua komentar berbentuk perintah. Keduanya sudah lebih baik karena menyertakan alasan (agar, karena), namun bentuk pertanyaan (“Bagaimana kalau nama variabel diganti totalHarga agar maksudnya terbaca?”) tetap lebih membuka diskusi.
  3. Deteksi alasan (contains): hanya dua dari lima komentar membawa alasan — ukuran sederhana yang bisa ditingkatkan sebelum PR selesai direview.
  4. Sisanya terklasifikasi apresiasi: satu komentar positif spesifik menjaga keseimbangan — persis peran aturan n+1.
  5. Batas heuristik: klasifikasi awalan sederhana keliru untuk kalimat majemuk; alat sungguhan perlu analisis kalimat. Untuk refleksi tim, heuristik kasar seperti ini sudah cukup memicu diskusi tentang kebiasaan komentar.

Budaya Persetujuan #

Persetujuan akhir menutup siklus, dan cara memberikannya menentukan apakah review dihormati. Beberapa kesepakatan yang terbukti sehat: bedakan komentar blocking (harus direspons sebelum merge: bug, celah keamanan) dari non-blocking (saran; boleh ditunda dengan catatan); penulis merespons setiap komentar, minimal dengan “dicatat di backlog”; dan reviewer menyetujui hanya setelah diskusi blocking tuntas. Diskusi yang tidak selesai dalam komentar berlanjut ke percakapan singkat — bukan baku argumen komentar yang saling memanjang.

Terakhir, review menilai kode, bukan orang. Komentar “method ini sulit diikuti” berbeda dunia dari “kamu membingungkan”; budaya tanpa saling menyalahkan membuat orang berani mengirim PR lebih awal — dan PR yang tiba lebih awal selalu lebih murah diperbaiki daripada yang menumpuk. Dengan ini rangkaian Section debugging dan code quality lengkap: membaca kegagalan, mengintip eksekusi, meninggalkan jejak teraudit, mencegah pola buruk otomatis, menjaga struktur, mengelola kompromi, dan memeriksa karya satu sama lain secara manusiawi — fondasi yang membuat program Java skala besar tetap dapat dirawat bertahun-tahun.

Referensi #

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

AnalisisKomentar.java

Unduh berkas
java
import java.util.ArrayList;
import java.util.List;

public class AnalisisKomentar {

    // Komentar review beku; klasifikasi berbasis awalan dan kata kunci sederhana
    static final List<String> KOMENTAR = List.of(
            "Mengapa validasi umur hanya terjadi di method ini?",
            "Bagaimana kalau input bernilai null saat panggilan pertama?",
            "Ubah nama variabel tmp menjadi totalHarga agar maksudnya terbaca.",
            "Jangan pakai System.out.println di kode produksi karena level tidak bisa disaring.",
            "Bagus, penanganan error di sini sudah rapi dan teruji."
    );

    public static void main(String[] args) {
        List<String> rincian = new ArrayList<>();
        int pertanyaan = 0;
        int perintah = 0;
        int apresiasi = 0;
        int denganAlasan = 0;

        for (String komentar : KOMENTAR) {
            String jenis;
            if (komentar.startsWith("Mengapa") || komentar.startsWith("Bagaimana kalau")) {
                jenis = "pertanyaan";
                pertanyaan++;
            } else if (komentar.startsWith("Ubah") || komentar.startsWith("Jangan")) {
                jenis = "perintah";
                perintah++;
            } else {
                jenis = "apresiasi";
                apresiasi++;
            }
            if (komentar.contains("karena") || komentar.contains("agar")) {
                denganAlasan++;
            }
            rincian.add("[" + jenis + "] " + komentar);
        }

        for (String r : rincian) {
            System.out.println(r);
        }

        System.out.println();
        System.out.println("Pertanyaan  : " + pertanyaan);
        System.out.println("Perintah    : " + perintah);
        System.out.println("Apresiasi   : " + apresiasi);
        System.out.println("Dengan alasan: " + denganAlasan + " dari " + KOMENTAR.size()
                + " komentar");
    }
}