Biaya yang Tidak Pernah Dimaksud oleh YAGNI
(newsletter.kentbeck.com)- YAGNI bukan aturan penghematan sederhana yang mengatakan “jangan menulis kode yang belum dibutuhkan”, melainkan prinsip yang membahas biaya dari mengambil alih struktur berdasarkan tebakan sebelum kebutuhan dipastikan
- Inti masalahnya bukan desain itu sendiri, melainkan kapan harus mendesain; strukturisasi yang terlalu dini bisa sama berbahayanya dengan strukturisasi yang terlalu terlambat
- Struktur di awal menciptakan sekaligus biaya opsi, yaitu menutup pilihan sebelum informasi datang, dan biaya NPV, yaitu memajukan biaya dan menunda pendapatan
- Meski biaya pembuatan kode mendekati nol, YAGNI tidak hilang; justru pembuatan yang murah dapat membuat framework berbasis tebakan lebih mudah dibuat
- Kesimpulan untuk membuat saat dibutuhkan bukan karena biaya menulis kode, melainkan karena nilai opsi yang belum digunakan dan uang yang belum dibelanjakan masih tetap ada
YAGNI tidak melarang desain
- YAGNI adalah singkatan dari “You Aren’t Gonna Need It”, dan bukan alasan untuk sama sekali tidak mendesain sesuatu yang belum dibutuhkan
- Jika ada sesuatu yang dibutuhkan, buatlah; namun intinya adalah timing
- Titik awalnya adalah anekdot dalam proyek ketika situasi “3 minggu lagi implementasi sederhana tidak akan cukup, jadi saya ingin membuat sesuatu yang lebih kompleks sekarang” berulang kali dijawab dengan “You aren’t going to need it”
- Prinsip ini memandang pembuatan struktur yang terlalu dini maupun yang terlalu terlambat sebagai hal yang berisiko
Masalahnya bukan biaya menulis kode, melainkan struktur berbasis tebakan
- Penafsiran umum melihat YAGNI sebagai aturan penghematan: “kode yang belum dibutuhkan itu mahal, jadi jangan menulisnya”
- Namun sasaran YAGNI bukan biaya produksi kode, melainkan struktur spekulatif (speculative structure) yang dibuat sebelum benar-benar dibutuhkan oleh fitur nyata
- Struktur seperti ini menimbulkan dua jenis biaya pada waktu dan karena alasan yang berbeda
Biaya pertama: opsi
- Jika struktur dibuat sebelum fitur datang, Anda akan berkomitmen berdasarkan tebakan terhadap kebutuhan yang belum diketahui
- Fitur yang sudah diantisipasi sebelumnya biasanya berbeda dari fitur yang benar-benar datang, sehingga Anda membayar biaya dua kali
- Biaya untuk mengakali struktur yang bentuknya keliru
- Biaya untuk membongkar kembali struktur tersebut
- Masalah ini tidak berhenti pada sekadar “prediksi itu sulit”
- Bahkan jika tebakannya benar, kerugian tetap ada karena Anda kehilangan opsi untuk tidak berkomitmen lebih dulu dan membuat struktur yang tepat nanti
- Menunggu bukan kemalasan, melainkan mempertahankan aset berupa opsi
Biaya kedua: NPV
- Sebagaimana uang memiliki nilai waktu, fitur juga memiliki nilai waktu
- Jika Anda membuat struktur sekarang untuk fitur yang dibutuhkan 3 bulan lagi, biaya dimajukan dan rilis fitur yang benar-benar menghasilkan uang tertunda
- Biaya ini tetap muncul meski tebakannya benar
- Prediksi yang sempurna sekalipun tidak dapat mengubah urutan biaya dan pendapatan; kerugian muncul dari jarak waktu ketika biaya ditempatkan sebelum pendapatan
- Biaya opsi adalah persoalan “jangan berkomitmen sebelum informasi datang”, sedangkan biaya NPV adalah persoalan “jangan membayar sebelum dibutuhkan”
- Meski ada bantahan bahwa “memperbaikinya nanti akan terlalu mahal”, perombakan mahal itu sendiri bisa jadi hanyalah sebuah prediksi lagi
Meski pembuatan kode menjadi murah, YAGNI tetap ada
- Tidak satu pun dari kedua biaya tersebut mencakup biaya mengetik kode
- Jika biaya menulis kode mendekati nol, penafsiran YAGNI sebagai penghematan—“karena kode sudah murah, bukankah boleh dibuat lebih dulu?”—runtuh
- Namun karena YAGNI bukan aturan penghematan, pembuatan kode yang murah tidak membuat YAGNI dibuang
- Biaya opsi muncul bukan dari jumlah usaha, melainkan dari komitmen yang menutup pilihan di masa depan
- Biaya NPV muncul bukan dari harga produksi, melainkan dari timing arus kas
- Pembuatan gratis tidak melemahkan YAGNI; justru membuat framework berbasis tebakan lebih mudah dibuat
- Struktur yang dihasilkan tetap menciptakan dua biaya tersebut, dan karena Anda tidak menulisnya sendiri, tingkat pemahamannya bisa lebih rendah
- Kesimpulannya bukan “tunggulah karena kode mahal”, melainkan buatlah saat dibutuhkan karena opsi dan uang lebih bernilai ketika belum digunakan
1 komentar
Komentar Hacker News
Saya rasa biaya perubahan struktur juga sudah turun
Berkat AI, biaya untuk memperkuat perilaku dengan pengujian sebelum perubahan struktur berkurang, dan biaya implementasi migrasi tanpa downtime juga turun
Salah satu alasan besar Rust mendapat perhatian bahkan sebelum AI adalah karena biaya perubahan struktur internal aplikasi rendah, dan sekarang makin begitu
Opportunity cost akibat tidak bisa mengubah struktur dengan aman telah naik besar, dan sekarang kami mengoptimalkan terutama untuk kemampuan mengubah bagian besar kode dan produk dengan cepat dan aman
Namun sebelum AI, perubahan struktur memakan waktu jauh lebih lama, jadi bisa juga dilihat bahwa nilai dari hal yang kini ingin dioptimalkan justru menurun
Masih bernilai, tetapi mungkin sedikit lebih rendah daripada dulu
Dengan bertambahnya pengujian buatan AI yang rapuh, biaya perubahan struktur justru lebih besar daripada sebelumnya
Merapikan sekumpulan pengujian agar memverifikasi inti masalah dan tidak memverifikasi keputusan desain yang kebetulan terjadi masih bukan hal yang bisa dilakukan AI dengan baik
Namun tanpa melakukan itu, sangat mudah mendapatkan kumpulan pengujian rapuh yang kira-kira baru 75% matang
Banyak orang merasa puas karena menganggap perpindahan dari “beberapa pengujian biasa dan rapuh yang ditulis manusia” ke “banyak pengujian biasa dan rapuh yang ditulis AI” sebagai peningkatan objektif
Saya sepenuhnya setuju bahwa alat ini dimanfaatkan dengan cara seperti itu, tetapi sulit mengatakan bahwa karena itu kita tidak perlu khawatir membangun istana di awang-awang yang keliru terlalu dini
Kontrak pengujian yang sempurna dan tahan refactoring masih cukup sulit dirancang
Sesuatu yang lama kembali terasa baru
Dari efisiensi konteks pendekatan seperti DDD atau clean architecture hingga hal-hal seperti ini, AI tidak menciptakan trade-off baru, melainkan bertindak seperti amplifier
Ia meningkatkan produktivitas tim yang melakukannya dengan benar, sekaligus memperbesar utang tim dengan standar kualitas desain dan arsitektur yang rendah
Satu-satunya yang didapat adalah tidak perlu berpikir mendalam
Berpikir mendalam tidak memakan waktu atau usaha sebanyak itu, jadi mereka akan kalah dari orang-orang yang memanfaatkan AI dengan cara yang sama tetapi tetap berpikir secukupnya agar tidak menjadi kerja sia-sia
Kent Beck membandingkan kode yang belum ditulis dengan opsi finansial untuk membeli kode pada harga tertentu
Namun itu tetap hanya analogi, dan jika ditarik terlalu jauh akan menjadi aneh
Jika belum menulis kode sama sekali, apakah pilihannya tak terbatas? Meski belum menghabiskan waktu, itu tampaknya tidak benar
Ini juga bisa menjadi alasan untuk tetap berada di tahap perencanaan dan menunda penulisan kode tanpa batas demi tidak menetapkan apa pun
Namun jika analogi ini bekerja, biayanya mungkin ada pada membaca kode
Kode yang tidak ditulis tidak perlu dibaca, dan jika memakai coding agent, kode itu juga tidak mengotori konteks dengan detail yang tidak relevan
Kode yang belum ditulis juga tidak perlu diuji, dan pengujian yang belum ditulis juga tidak memakan waktu eksekusi
Karena itu, sebaiknya proyek dijaga sekecil mungkin, dan menunda fitur dapat memperlambat pertumbuhan codebase semaksimal mungkin
Ini juga berarti menjalankan kode orang lain dapat menghindarkan banyak biaya
Jika bisa memakai API standar, kita tidak perlu memahami implementasinya secara rinci atau menjalankan pengujiannya, tetapi menambahkan dependensi punya risiko
Kode yang belum ditulis tidak punya nilai
Agar kode yang ditulis hari ini menciptakan nilai, ia harus menyelesaikan permintaan atau isu hari ini, atau condong membuat sesuatu besok menjadi lebih mudah
Jika berutang teknis lewat solusi hacky atau membuang waktu untuk sesuatu yang bertentangan dengan YAGNI, itu tidak menciptakan nilai
Yang penting bukan kode yang belum ditulis, melainkan kode yang akan ditulis ke depan dan tujuannya
Kita harus membuat trade-off yang tepat antara menyelesaikan tiket/tugas hari ini dan tidak menembak kaki diri sendiri di masa depan
Menulis kode adalah komitmen, dan nilai hari ini terlihat, sedangkan nilai esok lebih mirip estimasi
Meski begitu, selalu ada biaya yang akan dibayar nanti, jadi kita memperkirakan apa yang akan dibutuhkan untuk mencoba meminimalkan biaya
Saya rasa praktik terbaik di era AI belum cukup ditekankan, tetapi ada bagian yang benar-benar terlewat oleh Kent
Ada nilai besar dalam mengetahui lebih cepat fitur apa yang dibutuhkan
Membuat struktur spekulatif bisa menjadi mekanisme paksa untuk memantapkan requirement, atau setidaknya mulai memperlihatkan pola kegagalannya
Ini bisa lebih mahal daripada menunggu, jadi tidak boleh dilakukan untuk sebagian besar requirement, tetapi kadang bisa menjadi pilihan terbaik
Biaya membuat hal yang salah kini jauh lebih rendah, sehingga perhitungan seputar YAGNI juga berubah
Namun perhitungannya tetap diperlukan, dan sekarang setiap tim harus mencari sendiri bagaimana hal itu berubah bagi mereka
Jika tidak dibuang, itu menjadi mekanisme paksa untuk menghasilkan sesuatu yang berantakan
YAGNI adalah masalah membuat sesuatu yang tidak ada dalam requirement saat ini karena memperkirakan requirement akan berubah nanti
Itu berbeda dari memperjelas requirement dan batasan saat ini
Hal-hal seperti itu terutama berasal dari percakapan dengan pemangku kepentingan, pengguna, pelanggan, serta dari sumber daya, batasan rekayasa, dan kapabilitas
Prototipe bernilai ketika berbicara dengan pemangku kepentingan, membuat model manajemen proyek, atau melakukan riset rekayasa
Di luar itu, urutannya terbalik
Pendekatan melihat software yang sedang berjalan sebagai aset itu benar
Namun biaya menjalankannya dan membuatnya ulang sudah turun besar
Biaya yang belum turun adalah biaya memutus rantai kepercayaan terhadap hasil yang dapat diprediksi
Versi tertentu dari software yang sedang berjalan telah mengakumulasi kepercayaan, dan jika ditulis ulang dari awal, modal itu akan direset saat rilis
Pada suatu titik, cara berpikir saya berubah
Saya menunda hal-hal konkret dengan YAGNI, dan sebisa mungkin menulis versi yang abstrak
Haruskah membuat UserStore? Itu terlihat paling sederhana, tetapi mungkin saja tidak diperlukan bentuk spesifik bernama User
Jadi saya membuat Store yang bisa menampung apa pun yang dapat disimpan
Jika belum terbiasa, ini terlihat seperti overengineering dan penuh generic, tetapi secara paradoks ini adalah cara yang paling sedikit berkomitmen pada implementasi konkret apa pun
Bukan hanya membuat antarmuka UserStore yang mungkin tidak diperlukan, tetapi juga sampai membuat abstraksi Store yang digeneralisasi dan jelas tidak diperlukan
Demi tidak berkomitmen pada implementasi konkret, Anda justru mengimplementasikan lapisan-lapisan lengket yang tidak diperlukan dan besar kemungkinan juga tidak akan diperlukan ke depannya
Jika abstraksinya tidak didasarkan pada kebutuhan nyata, bahkan ketika nanti diperlukan pun kemungkinan besar bentuknya sudah keliru
Pada akhirnya UserStore akan dibutuhkan, jadi seharusnya itu yang dibuat lebih dulu
Saya tidak setuju dengan “ini bukan argumen bahwa prediksi sulit, seolah arsitek yang lebih tajam bisa menghindarinya”
Argumen ini hanya berlaku jika premisnya adalah prediksi itu sulit
Jika Anda menyiapkan pijakan lebih awal untuk fitur yang kemungkinannya sangat tinggi lalu semuanya sesuai, Anda bisa merilis lebih cepat
Tidak ada jaminan tim pasti membesar atau jumlah orangnya bertahan, jadi merayakan sikap menahan diri terasa lebih buruk daripada kelabakan mengejar YAGNI tepat sebelum tenggat
Baru-baru ini saya harus keluar secara fungsional dari codebase yang penuh tumpukan YAGNI, dan meskipun ada agent, itu adalah pekerjaan yang luar biasa besar
Dalam sistem terdistribusi, bagaimana kita tahu apa yang benar-benar sedang digunakan? Ada hal yang saya lewatkan dan ada juga yang dilewatkan agent, dan keseluruhannya memakan waktu lebih lama dari seharusnya
Ini juga bukan sekadar porting 1:1; karena saya menjadikannya kesempatan untuk menyederhanakan, saya harus memahami sepenuhnya bagaimana sistem lama bekerja
Hal-hal yang sebenarnya sama sekali tidak digunakan pun, jika tidak bisa diidentifikasi demikian, tetap masuk ke dalam hal yang harus dipahami
Pada akhirnya, menurut saya ini bermuara pada eksplorasi masalah dan implementasi solusi
Selalu ada biaya untuk memecahkan masalah yang salah, dan ada juga biaya untuk mengimplementasikan solusi buruk bagi sesuatu yang bahkan tidak diperlukan
Pengembangan perangkat lunak kadang bisa berubah menjadi sekadar trial and error, alih-alih memikirkan strategi eksplorasi dan kumpulan masalah yang perlu ditelusuri
Ada kalanya mengeksplorasi masalah lebih dalam ke arah tertentu daripada yang diperlukan dapat membantu dalam jangka panjang, tetapi mengimplementasikan solusi tanpa tujuan tidak pernah baik
Menurut saya, yang sebenarnya dikritik Kent Beck adalah sikap mengimplementasikan sesuatu “untuk berjaga-jaga” hanya karena mungkin akan diperlukan di masa depan
Ia mengatakan “jika membuat struktur sebelum fiturnya datang, itu berarti berkomitmen pada tebakan”, tetapi menurut saya, di kedua sisi tetap ada tebakan
Kemungkinan fitur itu datang bisa tinggi, tetapi tidak pasti
Jika tidak membuat strukturnya sekarang, ada biaya refactoring; jika membuatnya terlalu dini lalu fiturnya tidak datang, upaya menjadi sia-sia
Berapa biaya, probabilitas, dan trade-off di antara kemungkinan-kemungkinan itu? Tentu saja tergantung situasi
Seluruh YAGNI pada dasarnya adalah generalisasi besar yang disengaja
Pada akhirnya semuanya bergantung pada keadaan
Di kedua sisi, sering kali ada banyak tebakan dan penjelasan yang mengawang, dan ini sama seperti masalah estimasi kerja yang dapat dipercaya
Sebagian developer yang tidak tahan dengan dunia yang tidak pasti cenderung mencari aturan hitam-putih untuk segala hal
https://www.sebastiansylvan.com/post/the-perils-of-future-co...
Ringkasnya, tulisan itu berpihak pada YAGNI
Saya belum pernah melihat apa pun dalam tulisan Kent Beck yang mungkin berguna bagi perusahaan chip
Di perusahaan chip, banyak orang harus bekerja dalam jangka waktu lama, pelanggan tidak bisa melihat apa pun sampai selesai, dan untuk menghasilkan uang harus menjual dalam skala jutaan unit
Hardware memiliki batasan yang kuat
Alasan software diciptakan sejak awal juga justru untuk lepas dari batasan-batasan semacam itu
Memang banyak perusahaan chip tidak membagikan pekerjaan yang sedang berjalan, tetapi simulasi, prototipe, dan engineering sample bisa dibagikan dan memang terjadi
Tentu saja biasanya harus pelanggan besar
Wawasan dari industri dengan biaya perubahan yang relatif kecil tidak mudah diterapkan pada industri dengan biaya perubahan besar, dan sebaliknya juga sering demikian
Bagaimana perusahaan chip merencanakan proyek semacam itu? Agile, waterfall, atau memakai framework yang berbeda dari industri software?