Clean Code & Quality15 menit baca

A Philosophy of Software Design

oleh John Ousterhout

Ketika Kode yang "Jalan" Ternyata Bom Waktu

Bayangkan Anda baru gabung di sebuah tim, disuruh menambah satu fitur kecil—cuma menambah satu validasi di form. Terlihat sepele. Tapi begitu Anda buka kodenya, ternyata satu perubahan kecil ini memaksa Anda menyentuh tujuh file berbeda, tiga class yang saling bergantung dengan cara yang tidak jelas, dan satu fungsi bernama `handleData()` yang entah kenapa juga mengurus autentikasi.

Ini bukan kode yang buruk karena programmernya malas. Ini kode yang ditulis oleh orang-orang pintar, dikerjakan terburu-buru, bertumpuk selama bertahun-tahun—dan setiap orang yang menyentuhnya membuatnya sedikit lebih rumit, tanpa ada yang benar-benar bermaksud jahat.

John Ousterhout, profesor Stanford yang juga pencipta bahasa pemrograman Tcl dan salah satu arsitek di balik Google File System, menghabiskan puluhan tahun mengajar dan mengamati mengapa sistem software—yang ditulis oleh orang-orang cerdas—tetap saja berakhir jadi rumit dan sulit dipelihara.

Jawabannya, kata Ousterhout, bukan soal algoritma atau bahasa pemrograman apa yang dipakai. Jawabannya soal satu hal yang jarang diajarkan secara eksplisit: desain.

Contoh Analogi

Bayangkan Anda menata gudang. Ada dua cara: taruh barang di kotak besar berlabel jelas ("Alat Dapur"), atau taruh di ratusan kotak kecil masing-masing berisi satu-dua barang dengan label super spesifik ("Sendok Ukuran Sedang #3"). Kotak kecil terdengar rapi di atas kertas, tapi begitu Anda butuh masak, Anda harus buka belasan kotak cuma untuk cari semua yang dibutuhkan. Kode yang baik lebih mirip kotak besar berlabel jelas—sederhana dari luar, tapi menyimpan banyak hal berguna di dalamnya.

Selamat datang di dunia desain software yang sesungguhnya.


Bagian 1: Kompleksitas Adalah Musuh Sesungguhnya

Bukan Bug, Tapi Kompleksitas

Ousterhout membuka bukunya dengan klaim berani: masalah terbesar dalam software bukan bug, bukan performa—tapi kompleksitas. Kompleksitas ini sifatnya akumulatif, menumpuk sedikit demi sedikit lewat ratusan keputusan kecil yang masing-masing kelihatan tidak berbahaya.

Ousterhout mendefinisikan kompleksitas lewat dua komponen: dependencies (seberapa banyak bagian kode yang saling terikat, sehingga mengubah satu bagian memaksa Anda mengubah bagian lain) dan obscurity (seberapa tidak jelas maksud dan cara kerja sebuah kode).

Tiga Gejala Kompleksitas

Change amplification — satu perubahan kecil memaksa Anda mengubah kode di banyak tempat berbeda. Cognitive load — makin banyak hal yang harus diingat programmer sebelum bisa mengubah sesuatu dengan aman. Unknown unknowns — yang paling berbahaya: Anda bahkan tidak tahu bagian mana saja yang harus diubah, atau informasi apa yang perlu Anda tahu sebelum mengubah sesuatu.

Complexity is anything related to the structure of a software system that makes it hard to understand and modify.

Bagian 2: Deep Module vs Shallow Module

Ousterhout memperkenalkan salah satu konsep paling terkenal dari buku ini: modul yang baik itu deep, bukan shallow.

Apa Itu Deep Module

Deep module punya interface yang sederhana, tapi menyembunyikan functionality yang dalam dan berguna di baliknya. Contohnya sistem file di kebanyakan bahasa pemrograman—Anda cukup panggil `open()`, `read()`, `write()`, `close()`, padahal di baliknya ada logika rumit soal disk, caching, dan permission.

Apa Itu Shallow Module

Shallow module kebalikannya: interface-nya hampir sama rumitnya dengan implementasinya sendiri. Sering muncul ketika developer terlalu menganut prinsip "satu class harus melakukan satu hal" secara ekstrem, sampai akhirnya sebuah sistem dipecah jadi puluhan class kecil yang masing-masing cuma membungkus satu-dua baris logika. Alih-alih menyederhanakan, ini justru menambah beban kognitif—programmer harus melompat dari satu file ke file lain hanya untuk memahami satu alur logika sederhana.

The best modules are those whose interfaces are much simpler than their implementations.

Bagian 3: Design It Twice

Salah satu saran paling praktis dari Ousterhout: jangan pernah pakai desain pertama yang terlintas di kepala.

Kenapa Desain Pertama Jarang yang Terbaik

Desain pertama biasanya lahir dari solusi paling jelas yang muncul di benak—bukan solusi terbaik. Ousterhout menyarankan setiap kali menghadapi keputusan desain penting, buat minimal dua alternatif yang benar-benar berbeda pendekatannya, bandingkan trade-off masing-masing, baru putuskan.

Manfaat yang Tidak Terduga

Proses ini bukan cuma menghasilkan desain yang lebih baik, tapi juga melatih intuisi desain dari waktu ke waktu—programmer yang terbiasa membandingkan alternatif akan makin cepat "mencium" desain yang buruk di masa depan, bahkan tanpa harus menuliskannya secara eksplisit lagi.


Bagian 4: Comments Bukan Soal "Apa", Tapi "Kenapa"

Banyak programmer menganggap comment sebagai formalitas atau bahkan hal yang tidak perlu kalau kodenya sudah "self-explanatory". Ousterhout tidak setuju.

Comment Sebagai Sinyal Desain

Kalau sebuah kode butuh comment untuk menjelaskan apa yang sedang dilakukannya baris demi baris, itu biasanya pertanda desainnya kurang jelas—bukan pertanda comment-nya yang kurang. Comment yang baik justru menjelaskan hal-hal yang tidak bisa dilihat langsung dari kode: kenapa sebuah keputusan diambil, asumsi apa yang mendasarinya, atau efek samping apa yang perlu diwaspadai.

Kapan Comment Ditulis

Ousterhout menyarankan menulis comment justru sebelum menulis kodenya—bukan setelahnya. Menulis comment di awal memaksa programmer memikirkan dulu abstraksi dan interface-nya dengan jernih, sebelum tenggelam dalam detail implementasi.


Bagian 5: Pull Complexity Downward

Prinsip ini sering berlawanan dengan insting kebanyakan programmer.

Siapa yang Harus Menanggung Kompleksitas

Ketika sebuah modul punya kompleksitas yang tidak bisa dihindari, ada dua pilihan: biarkan modul itu tetap sederhana dan pindahkan beban kompleksitasnya ke setiap orang yang memakainya, atau modul itu sendiri yang menanggung kompleksitas ekstra demi menjaga penggunanya tetap sederhana.

Ousterhout dengan tegas memilih opsi kedua: lebih baik satu developer modul menanggung sedikit kompleksitas ekstra, daripada memaksa semua pengguna modul—yang jumlahnya bisa jauh lebih banyak—ikut menanggung beban yang sama berulang kali.

It's better for a module to have a slightly more complex implementation if that keeps the interface simpler.

Bagian 6: Pelajaran untuk Hari Ini

1. Setiap Kode Baru, Tanya Dulu Soal Interface

Sebelum menulis implementasi, tanyakan: apakah interface ini benar-benar menyembunyikan kompleksitas, atau cuma menambah satu lapisan lagi yang harus diingat orang lain?

2. Jangan Pecah Class Terlalu Kecil

Class atau fungsi yang terlalu kecil sering terasa "bersih" tapi justru menambah beban kognitif. Pertimbangkan menyatukan hal-hal yang selalu berubah bersamaan.

3. Bandingkan Minimal Dua Desain

Jangan langsung eksekusi desain pertama yang terlintas. Luangkan waktu membuat alternatif, meski hanya di atas kertas.

4. Comment Itu Soal "Kenapa", Bukan "Apa"

Kalau merasa perlu menjelaskan apa yang dilakukan sebuah baris kode, pertimbangkan menulis ulang kodenya dulu—baru tambahkan comment untuk konteks yang tidak terlihat dari kode itu sendiri.

5. Tanggung Kompleksitas di Tempat yang Tepat

Kalau ragu, lebih baik kompleksitas ditanggung oleh satu modul yang jarang diubah, daripada dibebankan ke banyak pemakainya.


Penutup

John Ousterhout tidak menjanjikan rumus ajaib untuk menulis kode sempurna. Yang ditawarkannya adalah cara berpikir—sebuah lensa untuk terus-menerus bertanya "apakah keputusan ini menambah atau mengurangi kompleksitas sistem?"

Pertanyaan itu sederhana untuk diucapkan, tapi butuh latihan bertahun-tahun untuk benar-benar dikuasai sebagai insting. Buku ini adalah titik awal yang baik untuk melatihnya.

Kompleksitas tidak pernah hilang sepenuhnya dari sebuah sistem software—ia hanya bisa dipindahkan, disembunyikan, atau dikelola dengan lebih bijak. Pilihan Anda sebagai desainer adalah ke mana kompleksitas itu akan pergi.


Tentang Buku Asli

"A Philosophy of Software Design" pertama terbit tahun 2018 dan sejak itu jadi salah satu bacaan wajib di banyak kelas software engineering, termasuk kelas CS190 yang diajarkan Ousterhout sendiri di Stanford.

John Ousterhout adalah profesor ilmu komputer di Stanford University, pencipta bahasa pemrograman Tcl, dan salah satu peneliti di balik Google File System serta sistem Raft consensus algorithm. Latar belakangnya yang menggabungkan riset akademis dan pengalaman langsung membangun sistem skala besar membuat argumennya jarang terasa teoretis semata.

Buku ini relatif tipis dibanding buku software engineering kebanyakan, tapi padat—setiap babnya menantang asumsi umum yang sering diajarkan tanpa dipertanyakan, termasuk beberapa prinsip populer seperti "functions should be short" yang menurut Ousterhout justru bisa jadi kontraproduktif kalau diterapkan tanpa nalar.

Untuk memahami sepenuhnya contoh kode dan studi kasus yang dibahas Ousterhout, buku aslinya sangat layak dibaca. Ringkasan ini menangkap gagasan pokoknya—tapi buku utuhnya menyuguhkan nuansa dan contoh konkret yang hanya bisa didapat dengan membaca seluruh uraiannya.

Bagi siapa pun yang menulis kode setiap hari—baik sendirian maupun dalam tim besar—buku ini adalah pengingat bahwa keputusan desain kecil yang terlihat sepele hari ini, bisa jadi bom waktu kompleksitas beberapa bulan ke depan.

Selamat! Kamu telah menyelesaikan ringkasan ini.
Baca Buku Lainnya →

Buku serupa

Cover The Pragmatic Programmer: Your Journey to Mastery
Clean Code & Quality

The Pragmatic Programmer: Your Journey to Mastery

oleh David Thomas & Andrew Hunt

Programmer hebat bukan yang hafal paling banyak bahasa pemrograman, tapi yang paling disiplin menjaga kualitas kerjanya sendiri.

15 min baca