Dulu saya cukup sering menghabiskan waktu memikirkan arsitektur sebelum benar-benar menulis kodenya.
Rasanya masuk akal. Kalau dari awal desainnya sudah benar, bukankah pekerjaan setelahnya akan jauh lebih mudah?
Saya pikir begitu selama bertahun-tahun.
Saya mencari struktur yang paling tepat, abstraksi yang paling masuk akal, pembagian service yang paling bersih. Kadang bahkan belum ada satu baris kode pun, tapi di kepala saya sistemnya sudah harus terlihat rapi.
Belakangan saya sadar, ada sesuatu yang keliru dari cara berpikir itu.
Bukan karena perencanaan itu buruk. Masalahnya adalah saya sering mencoba mendapatkan jawaban sebelum punya cukup pengalaman untuk tahu pertanyaannya.
Kesempurnaan yang belum pernah dipakai
Arsitektur yang terlihat sangat rapi di awal biasanya memang terlihat rapi karena belum pernah dipakai.
Belum ada requirement yang berubah.
Belum ada traffic yang aneh.
Belum ada developer lain yang mencoba memahami kode tersebut.
Belum ada bug yang memaksa kita mempertanyakan keputusan yang dulu terasa sangat masuk akal.
Jadi hampir semua yang kita desain di awal sebenarnya masih berupa dugaan.
Dan semakin banyak dugaan yang kita masukkan ke dalam arsitektur, semakin mahal pula kalau ternyata dugaan itu salah.
Saya pernah menganggap abstraksi sebagai sesuatu yang membuat kode lebih baik. Sekarang saya lebih hati-hati.
Abstraksi memang bisa membuat kode lebih baik.
Tapi abstraksi yang dibuat terlalu cepat juga bisa membuat kode jauh lebih sulit dipahami.
Karena kita akhirnya bukan cuma memecahkan masalah yang ada, tetapi juga memelihara solusi untuk masalah yang mungkin tidak pernah muncul.
Kode yang baik bukan kode yang tidak bisa diubah. Kode yang baik adalah kode yang murah untuk diubah.
Saya sekarang lebih suka keputusan kecil
Saya tidak lagi terlalu percaya pada arsitektur yang langsung lengkap sejak hari pertama.
Saya lebih suka membuat keputusan sekecil mungkin yang masih memungkinkan sistem berjalan.
Lalu melihat apa yang terjadi.
Kalau ternyata keputusan itu benar, kita punya bukti untuk mempertahankannya.
Kalau ternyata salah, kita masih punya ruang untuk mengubahnya.
Ini juga mengubah cara saya melihat abstraksi.
Kalau baru ada satu contoh, saya biasanya tidak buru-buru membuat interface.
Kalau baru ada satu implementasi, saya tidak selalu merasa perlu membuat factory.
Kalau baru ada satu service, saya tidak merasa harus langsung memecahnya menjadi lima service hanya supaya diagramnya terlihat bagus.
Mungkin nanti memang akan dibutuhkan.
Tapi saya lebih suka membiarkan kebutuhan itu muncul daripada menebaknya terlalu jauh.
Tidak semua kode harus terlihat cantik
Ada bagian dari kode yang memang akan terasa sedikit jelek.
Dan sekarang saya tidak selalu menganggap itu sebagai kegagalan.
Kadang kode yang sedikit jelek justru lebih jujur.
Ia mengatakan:
“Di bagian ini kita belum benar-benar tahu bentuk yang tepat.”
Menurut saya itu jauh lebih sehat daripada membuat abstraksi yang sangat elegan hanya untuk menutupi ketidaktahuan tersebut.
Karena kode akan terus berubah.
Requirement berubah. Cara kita memahami masalah berubah. Traffic berubah. Tim berubah. Bahkan asumsi kita sendiri tentang sistem bisa berubah.
Arsitektur yang baik bukan arsitektur yang berhasil memprediksi semua perubahan itu.
Saya rasa kita memang tidak mungkin melakukannya.
Arsitektur yang baik adalah arsitektur yang tidak terlalu melawan ketika perubahan akhirnya datang.
Mungkin itu alasan saya sekarang berhenti mengejar arsitektur yang sempurna.
Saya lebih tertarik membuat sesuatu yang cukup baik untuk dipakai, cukup sederhana untuk dipahami, dan cukup lentur untuk diubah ketika saya ternyata salah.
Karena biasanya, kita baru benar-benar tahu arsitektur yang kita butuhkan setelah sistemnya hidup.