Prinsip Clean Code dengan Contoh Laravel: Dari Controller Gemuk ke Kode Rapi

Kode yang berjalan belum tentu kode yang baik. Setiap developer pernah membuka controller berisi tiga ratus baris, dengan nama variabel $data2, if bersarang lima tingkat, dan angka...

Prinsip Clean Code dengan Contoh Laravel: Dari Controller Gemuk ke Kode Rapi

Kode yang berjalan belum tentu kode yang baik. Setiap developer pernah membuka controller berisi tiga ratus baris, dengan nama variabel $data2, if bersarang lima tingkat, dan angka 3 yang entah berarti apa. Mengubah satu aturan diskon di kode seperti itu bisa memakan setengah hari, dan sering merusak fitur lain tanpa disadari. Clean code adalah kebiasaan menulis kode yang mudah dibaca dan aman diubah, terutama oleh orang lain, termasuk diri Anda sendiri enam bulan kemudian.

Artikel ini membahas prinsip-prinsip yang paling terasa dampaknya di proyek Laravel sehari-hari, masing-masing dengan contoh kode sebelum dan sesudah dirapikan.

1. Nama yang Menjelaskan Maksud

Nama adalah dokumentasi yang paling sering dibaca. Nama yang baik menjawab "ini apa" dan "untuk apa" tanpa perlu membuka isi fungsinya.

// Sulit dipahami
$d = 30;
$x = Order::where('s', 2)->get();
function proses($a) { ... }

// Jelas
$batasHariJatuhTempo = 30;
$pesananBelumDibayar = Order::where('status', OrderStatus::Menunggu)->get();
function kirimPengingatTagihan(Order $order) { ... }

Pedoman praktis: variabel dan properti memakai kata benda ($totalBelanja), fungsi memakai kata kerja (hitungDiskon()), nilai boolean diawali is, has, atau bisa ($isLunas). Konsisten memakai satu bahasa dalam satu proyek juga membantu; campuran getPelanggan() dan ambilCustomer() membingungkan pembaca.

2. Kurangi If Bersarang dengan Early Return

Kode yang terus menjorok ke kanan memaksa pembaca mengingat banyak kondisi sekaligus. Tangani kasus gagal lebih dulu, lalu keluar.

// Sebelum: tiga tingkat if
public function bayar(Order $order)
{
    if ($order->user_id === auth()->id()) {
        if ($order->status === 'menunggu') {
            if ($order->total > 0) {
                // ... proses pembayaran
            }
        }
    }
}

// Sesudah: guard clause, alur utama tidak menjorok
public function bayar(Order $order)
{
    Gate::authorize('pay', $order);

    if ($order->status !== OrderStatus::Menunggu) {
        return back()->with('error', 'Pesanan ini sudah diproses.');
    }

    if ($order->total <= 0) {
        return back()->with('error', 'Total pesanan tidak valid.');
    }

    // ... proses pembayaran
}

3. Ganti Angka dan Teks Ajaib dengan Enum atau Konstanta

Angka 2 pada where('status', 2) tidak berarti apa-apa bagi pembaca baru, dan salah ketik 'lunass' tidak akan ketahuan sampai ada laporan bug. Sejak PHP 8.1, gunakan enum:

// app/Enums/OrderStatus.php
enum OrderStatus: string
{
    case Menunggu = 'menunggu';
    case Lunas    = 'lunas';
    case Batal    = 'batal';

    public function label(): string
    {
        return match ($this) {
            self::Menunggu => 'Menunggu Pembayaran',
            self::Lunas    => 'Lunas',
            self::Batal    => 'Dibatalkan',
        };
    }
}

// app/Models/Order.php
protected function casts(): array
{
    return ['status' => OrderStatus::class];
}

// Pemakaian
if ($order->status === OrderStatus::Lunas) { ... }

Editor sekarang bisa melengkapi nilai yang valid, salah ketik langsung menjadi error, dan label tampilan berada di satu tempat.

4. Controller Tipis: Pindahkan Validasi dan Logika Bisnis

Controller yang sehat cukup menerima request, memanggil logika, dan mengembalikan respons. Validasi dipindahkan ke Form Request, logika bisnis ke kelas tersendiri (sering disebut Action atau Service).

php artisan make:request StoreOrderRequest
// app/Http/Requests/StoreOrderRequest.php
public function rules(): array
{
    return [
        'items'              => ['required', 'array', 'min:1'],
        'items.*.product_id' => ['required', 'exists:products,id'],
        'items.*.qty'        => ['required', 'integer', 'min:1'],
    ];
}

// app/Actions/BuatPesanan.php
class BuatPesanan
{
    public function handle(User $user, array $items): Order
    {
        return DB::transaction(function () use ($user, $items) {
            $order = $user->orders()->create(['status' => OrderStatus::Menunggu]);
            foreach ($items as $item) {
                $product = Product::lockForUpdate()->findOrFail($item['product_id']);
                $product->decrement('stock', $item['qty']);
                $order->items()->create([
                    'product_id' => $product->id,
                    'qty'        => $item['qty'],
                    'price'      => $product->price,
                ]);
            }
            return $order;
        });
    }
}

// Controller menjadi sangat ringkas
public function store(StoreOrderRequest $request, BuatPesanan $buatPesanan)
{
    $order = $buatPesanan->handle($request->user(), $request->validated()['items']);
    return redirect()->route('orders.show', $order);
}

Keuntungannya nyata: logika BuatPesanan bisa dipakai ulang dari API atau command artisan, dan bisa diuji tanpa melewati HTTP. Detail aturan validasi dibahas di validasi form di Laravel dengan rapi.

5. Satu Fungsi, Satu Tanggung Jawab

Fungsi bernama simpanDanKirimEmailDanUpdateStok() adalah tanda fungsi itu mengerjakan terlalu banyak hal. Pecah menjadi beberapa fungsi kecil dengan nama yang jelas. Patokan sederhana: jika Anda kesulitan memberi nama tanpa kata "dan", atau fungsi tidak muat dalam satu layar, kemungkinan besar ia perlu dipecah.

6. DRY, tetapi Jangan Abstraksi Terlalu Dini

Prinsip Don't Repeat Yourself mengajak menghindari duplikasi logika. Namun menyatukan dua kode yang hanya kebetulan mirip sering berakhir dengan satu fungsi penuh parameter $mode dan if di mana-mana. Pegangan yang lebih aman: tunggu sampai pola yang sama muncul tiga kali dan alasannya memang sama, baru buat abstraksi.

7. Komentar Menjelaskan "Kenapa", Bukan "Apa"

// Buruk: mengulang apa yang sudah jelas dari kode
// tambah 1 ke counter
$counter++;

// Baik: menjelaskan alasan yang tidak terlihat dari kode
// Bank mitra hanya menerima nominal kelipatan 100, sisa pembulatan masuk biaya admin.
$nominalTransfer = floor($total / 100) * 100;

Jika sebuah blok kode butuh komentar panjang untuk menjelaskan apa yang dilakukannya, biasanya lebih baik dipindah ke fungsi dengan nama yang menjelaskan hal tersebut.

8. Biarkan Alat yang Menjaga Format

Perdebatan soal spasi dan letak kurung kurawal membuang waktu review. Proyek Laravel baru sudah menyertakan Laravel Pint:

vendor/bin/pint          # merapikan seluruh kode
vendor/bin/pint --test   # hanya mengecek, cocok untuk CI

Jalankan pint --test otomatis di setiap push seperti dijelaskan di CI/CD sederhana dengan GitHub Actions, sehingga review kode bisa fokus pada logika.

9. Test Membuat Refactor Aman

Merapikan kode tanpa test sama dengan merenovasi rumah dalam gelap. Sebelum memindahkan logika dari controller ke Action, tulis dulu feature test untuk alur tersebut, pastikan lulus, baru refactor dan jalankan ulang. Panduan memulainya ada di testing otomatis di Laravel untuk pemula.

Tanda-Tanda Kode Perlu Dirapikan

GejalaLangkah perbaikan
Controller lebih dari 200 barisPindahkan validasi ke Form Request, logika ke Action
If bersarang lebih dari dua tingkatEarly return / guard clause
Angka atau string status tersebar di banyak fileEnum dengan cast di model
Kode yang sama disalin di tiga tempat atau lebihEkstrak ke method, Action, atau scope Eloquent
Query berulang dengan kondisi yang samaLocal scope, lihat mengenal Eloquent ORM
Takut mengubah kode karena sering merusak fitur lainTulis feature test lebih dulu, baru refactor

Clean code tidak harus dikerjakan sekaligus. Terapkan aturan sederhana: setiap kali menyentuh sebuah file, tinggalkan dalam keadaan sedikit lebih rapi daripada saat Anda membukanya.

Ingin langsung mempraktikkannya?

Buat akun gratis untuk mengunduh contoh aplikasi Laravel, menyimpan tutorial favorit, dan mencoba kursus. Gratis, bisa daftar dengan akun Google.

Daftar Gratis Lihat katalog aplikasi
Yudhi
Ditulis oleh
Yudhi
Founder & Lead Developer, GudangCode

Yudhi adalah founder GudangCode dan developer Laravel dengan pengalaman membangun puluhan sistem informasi bisnis siap pakai — mulai dari POS, HRIS, hingga aplikasi manajemen. Ia menulis panduan dan artikel di GudangCode untuk membantu developer Indonesia menjalankan, memahami, dan men-deploy source code Laravel dengan benar.

Laravel PHP MySQL Sistem Informasi Bisnis
Lihat semua artikel Yudhi
Clean Code Teknologi & Development
Bacaan Paling Dicari
📚 Free Learning Hub

Learn Coding for Free at DhieCoderWeb

Explore Laravel, PHP, JavaScript tutorials, source code, web development guides, and practical programming tips.

DhieCoderWeb
100+
Tutorials
Free
Learning
SEO
Tips
Visit Dhiecoderweb.com →