Jari Tengah Chesterton
(arp242.net)- Chesterton’s fence adalah nasihat agar tidak sembarangan mengubah kode ketika kita tidak tahu alasannya, tetapi kode dan riwayat commit yang tidak meninggalkan alasan justru mewariskan beban yang sama kepada pengembang berikutnya
- Isi commit selama 13 tahun terakhir di repositori tersebut hanya berjumlah 295 baris menurut hitungan perintah; jika isi terkait dependabot, revert, dan typo dikeluarkan, jumlahnya turun menjadi 167 baris
- Judul commit pun, bahkan untuk perubahan besar, sering tidak memberi konteks seperti “fix page A”, dan hampir tidak ada dokumentasi terpisah maupun komentar kode, sehingga sulit menelusuri alasan perubahan
- Di dalam kode masih ada refactoring yang tidak selesai, sisa-sisa fitur yang sudah dihapus, fitur yang ditambahkan tetapi tidak terhubung atau tidak digunakan, serta fitur yang tampaknya tidak dipakai siapa pun
- Pesan commit dan dokumentasi setidaknya perlu meninggalkan catatan tentang “apa yang diubah, mengapa diubah, dan mengapa ini solusi yang baik”; jika tidak meninggalkan apa pun, biaya yang ditanggung pengembang setelahnya akan membesar
Beban yang Ditinggalkan Kode Tanpa Alasan
- Chesterton’s fence adalah metafora yang menyarankan agar kita tidak sembarangan mengubah sesuatu jika belum memahami mengapa hal itu dibuat seperti itu
- Dalam pemrograman juga, ada kalanya kita “memperbaiki” kode yang terlihat aneh lalu belakangan menyadari bahwa keanehan itu memang punya alasan
- Kasus ini menunjukkan masalah dari sisi sebaliknya
- Ada banyak kode dan keputusan yang aneh, tetapi tidak ada catatan yang menjelaskan mengapa semuanya menjadi seperti itu
- Setelah semua pengembang sebelumnya pergi, tidak ada lagi orang yang bisa ditanya
- Riwayat commit repositori ini nyaris tidak memberikan konteks yang berarti
- Total isi commit selama 13 tahun terakhir hanya 295 baris
- Jika isi commit dependabot, “revert commit”, dan “fix typo” dikeluarkan secara manual, tinggal 167 baris
- Kira-kira setara satu baris per bulan
- Judul commit pun umumnya tidak cukup untuk menjelaskan perubahan besar, misalnya hanya “fix page A”
- Tidak ada dokumentasi terpisah, dan komentar kode juga hampir tidak ada
- Situasi seperti ini lebih dekat ke jari tengah Chesterton: “kami melakukan banyak hal aneh, tetapi kami tidak akan memberi tahu kenapa”
Catatan Minimum yang Harus Ditinggalkan Pengembang
- Di codebase masih tersisa berbagai jenis kode yang belum tuntas atau sisa-sisa lama
- refactoring yang tidak selesai
- sisa dari fitur yang sudah dihapus
- fitur yang sudah ditambahkan tetapi tidak dihubungkan atau tidak digunakan
- fitur yang tampaknya tidak digunakan siapa pun
- Secara keseluruhan, masalah Chesterton’s gap juga tampak cukup parah
- Mirip situasi “belum ada pagar, jadi mari kita buat”, tanpa terlebih dahulu mempertanyakan apakah pagar itu memang diperlukan
- Menulis dengan baik itu sulit, tetapi meninggalkan penjelasan yang cukup layak untuk lolos sebetulnya tidak sulit
- Catatan perubahan pada dasarnya harus menjawab tiga pertanyaan
- Apa yang diubah
- Mengapa diubah
- Mengapa solusi ini bagus
- Kadang “Implement new feature X” saja sudah cukup, tetapi dalam kebanyakan kasus ada hal yang layak ditulis tentang mengapa atau bagaimana sebuah fitur ditambahkan dengan cara tertentu
- Untuk perbaikan bug, refactoring, dan perubahan yang substansial, biasanya kita bisa meninggalkan setidaknya satu atau dua paragraf tentang apa yang diubah dan alasannya
- Catatan seperti ini bukan opsi, melainkan bagian dari pekerjaan pengembang perangkat lunak
- Tidak harus indah
- Tidak harus memakai bahasa Inggris yang sempurna
- Tidak harus berupa esai besar
- Meskipun ada hal yang terlewat, itu tetap jauh lebih baik daripada tidak ada apa-apa
- Jika tidak meninggalkan apa pun, kita pada akhirnya melemparkan masalah itu kepada semua orang yang datang setelahnya
1 komentar
Komentar Lobste.rs
Terkadang tidak jelas pada saat itu hal apa yang nanti akan menjadi penting. Sangat membantu jika seluruh proses yang berujung pada commit tercatat secara terbuka, tetapi karena semua pihak yang terlibat sudah punya banyak konteks, ada juga hal-hal yang dianggap “terlalu jelas” sehingga terlewat
Jika diskusinya tidak tercatat, menggali proses pengambilan keputusan jadi jauh lebih sulit, seperti arkeologi digital. Pada akhirnya ada saatnya kita harus menghadapi keadaan di mana kita tidak tahu kenapa pagar itu ada, dan harus menilainya berdasarkan konteks saat ini serta pengetahuan sistem dari orang-orang sekarang
Sangat membantu jika ada orang yang tinggal lama di proyek dan mendapatkan pemahaman menyeluruh serta intuisi tentang keseluruhan sistem. Organisasi yang melihat developer sebagai roda gigi yang bisa saling menggantikan membuat tak ada seorang pun bertahan cukup lama, sehingga kesalahan yang sama terus terulang dan roda kembali diciptakan dari nol
Saat orang berikutnya melihat kodenya, setidaknya kemungkinannya tidak nol untuk bisa memahami kenapa dibuat seperti itu
Saya tidak pernah mengerti developer yang di pesan commit hanya menulis hal seperti “fix” atau “WIP commit”. Mungkin mereka belum pernah melakukan arkeologi kode secara serius, atau bahkan tidak pernah terpikir bahwa hal seperti itu bisa dilakukan
Saya selalu berusaha keliru ke arah terlalu banyak informasi. Dengan begitu, saya di masa depan, penerus saya, atau orang malang yang dipanggil saat terjadi insiden setidaknya punya peluang untuk memahami alasan ketika sesuatu akhirnya rusak
Dalam kasus seperti itu, sulit untuk terus melacak di kepala apa yang berubah setelah setiap checkpoint atau menambahkan penjelasan yang bermakna, dan commit lebih diperlakukan seperti tombol “save” di video game ketimbang sarana untuk membagi perubahan menjadi unit kerja yang terdefinisi dengan baik
Sebaliknya, jika menghasilkan commit besar dari refaktor API besar-besaran, kemungkinan besar penjelasan yang kurang dari setara dokumen desain akan tetap terasa kurang, dan kalau itu pun tidak akan dilakukan, makna dari pesan yang panjang juga jadi agak kabur. Namun, sebagian orang justru menganggap ini semacam lencana kehormatan lalu mulai menulis hal seperti “perbaikan bug dan peningkatan fitur” di catatan rilis, dan itu jelas kesimpulan yang salah
Banyak developer sering lupa bahwa “orang lain” yang harus membaca dan memahami latar belakang sebuah perubahan bisa jadi adalah diri mereka sendiri di masa depan. Semua orang pasti akrab dengan situasi menggaruk kepala melihat sebuah blok kode, lalu menjalankan
git blamedan mendapati nama sendiri menatap balikSudah tak terhitung berapa kali pesan commit yang bagus memangkas waktu berjam-jam, bahkan kadang berhari-hari, untuk mencari kenapa dengan membongkar issue, email, dan log chat. Bahkan dalam kasus ketika seharusnya saya bisa langsung menjawabnya pun begitu
Kita harus bersikap baik pada diri sendiri di masa depan. Sebaiknya tuangkan ke git log apa yang kita tahu, pikirkan, dan semua yang didiskusikan. Tidak pernah jelas hal apa yang masih akan tetap terasa jelas 5 tahun kemudian
git blame, setidaknya untuk hal-hal yang memang punya alasan, saya tidak terlalu sering mengalaminya. Untuk hal acak yang tampak seperti perilaku aneh dari orang lain, sulit memberi penjelasan yang berguna kalau tidak bisa melihat proses di pihak sana, tetapi kalau itu sesuatu yang dulu masuk akal bagi saya, biasanya saat dibaca ulang saya akan bisa memahaminya lagiCara belajar saya tampaknya lebih mirip lapisan lava yang menumpuk. Sejak SMA, alih-alih berubah besar, saya terus menambahkan apa yang saya tahu dan cara-cara yang bisa saya gunakan
Baru-baru ini ada seseorang yang berpendapat bahwa jika pesan commit lebih dari satu kalimat, itu umumnya buang-buang waktu, dan saya ingin membantahnya dengan tegas, tetapi ternyata saya tidak terlalu piawai membuktikan sebaliknya
Salah satu pertanyaannya adalah informasi seperti apa yang seharusnya masuk ke pesan commit, dan informasi seperti apa yang seharusnya masuk ke komentar inline, ADR, atau dokumentasi lain yang lebih panjang
Saya masih berusaha menulis pesan commit yang bagus, tetapi di tempat kerja situasinya sudah nyaris tidak tertolong, dan bahkan di proyek mainan pribadi saya pun tidak konsisten
Namun kode akhirnya tetap harus bisa dipahami tanpa membaca pesan commit. Jika ada bagian dalam kode baru yang memerlukan alasan, itu seharusnya masuk ke komentar
Dengan kata lain, pesan commit menjelaskan mengapa perubahan ini dilakukan sekarang, sedangkan komentar menjelaskan mengapa kode pada titik setelah perubahan itu selesai berada dalam keadaan seperti itu
Perubahan yang lebih besar, terutama fitur baru, seharusnya punya dokumen desain di suatu tempat. Jika perlu direview, itu bisa berupa dokumen nyata di dalam repositori, atau bisa juga ada di pelacak isu
Pesan commit seharusnya merujuk ke dokumen tersebut, dan mungkin juga perlu menjelaskan detail yang muncul ketika desain diturunkan menjadi kode. Jika memungkinkan, ada baiknya menyertakan abstrak singkat dari dokumen desain. Ini sangat penting ketika ada beberapa calon reviewer, untuk memberi sinyal siapa yang paling perlu memperhatikan, dan untuk menangkap jika ada orang yang seharusnya memberi masukan pada tahap desain tetapi terlewat
git logataujj log, melainkan hampir selalu lewat tampilan anotasi barisBaris judul secara umum sangat berguna untuk menilai apakah saya perlu menggali lebih dalam. Jika isi pesannya memuat informasi tentang mengapa perubahan itu dibuat, itu membantu ketika alasannya tidak intuitif
Misalnya, meskipun cukup banyak kode yang ditambahkan, sering kali “admin: add impersonation” saja sudah cukup. Tetapi untuk “auth: shorten JWT timeouts”, saya ingin melihat satu atau dua kalimat tentang mengapa batas waktunya perlu dipersingkat
Saya cenderung menganggap pesan commit yang benar-benar panjang pada praktiknya tidak terlalu berguna. Alasannya sebagian besar sama dengan yang ditunjukkan dalam tulisan itu. Format seperti itu tampaknya berasal dari alur kerja di mana pesan commit sekaligus menjadi deskripsi PR, misalnya alur berbasis email atau Gerrit. Dalam kasus seperti itu format tersebut tidak merugikan, tetapi saya juga sulit melihat bahwa itu selalu menambah nilai
Saya juga berada dalam situasi yang mirip. Di kelompok yang lebih luas di tempat kerja, hanya saya dan satu orang lain yang menulis pesan commit yang detail
Bahkan jika kita tahu mengapa pagar itu dibuat, kita belum tentu tahu mengapa sekarang pagar itu masih ada di sana. Bahkan jika kita adalah orang yang dulu membangun pagar ala Chesterton itu, kita belum tentu tahu apakah pagar itu bisa dibongkar
Pohon ketergantungan yang dimaksudkan saat sistem dibuat hanyalah subset dari pohon ketergantungan nyata pada suatu titik waktu. Jadi, meskipun seorang developer sempurna menjelaskan sepenuhnya mengapa pagar itu dibuat, manfaatnya tetap terbatas
Yang mereka tahu adalah mengapa itu dibuat, bukan jawaban atas pertanyaan, “kalau pagar ini dihapus, apa yang akan rusak?” Lihat saja https://xkcd.com/1172/. Di antara use case yang lucu memang ada yang bisa dianggap tidak penting, tetapi selalu ada penggunaan sah yang bahkan developer aslinya sendiri tidak tahu
Mengetahui apa yang dipikirkan developer asli, atau apa yang mereka hisap, memang menarik, tetapi informasi itu ada di suatu titik antara tidak lengkap dan tidak relevan
Sebagai contoh rekaan, bayangkan pagar Chesterton itu awalnya didirikan untuk menjauhkan anak-anak dari genangan air ketika di kedua sisinya masih ada lahan pertanian. Sekarang mungkin sudah ada jalan tol, dan pagar itu kebetulan menjadi satu-satunya mekanisme yang mencegah kematian massal hewan dan manusia akibat tabrakan rusa dengan mobil
Tidak ada yang tahu fakta ini. Kombinasi jalan tol + tanpa pagar bukan hanya belum pernah diuji, tetapi juga belum pernah ada, dan pembangun jalan tol maupun kementerian sumber daya alam tidak tahu mengapa roadkill di jalan itu sedikit. Beberapa tahun kemudian, ketika semua lahan pertanian berubah menjadi perumahan dan area itu bukan lagi koridor migrasi hewan utama, pagar itu mungkin menjadi tidak berguna, atau mungkin tidak
Jika ini terasa dibuat-buat atau tidak relevan bagi diri Anda, saya iri. Dalam pengalaman saya, kecuali perusahaan yang cukup besar dan tidak terlalu tua, kebanyakan hal memang berjalan seperti ini
Kebenarannya adalah, semua yang kita lakukan adalah bagian dari sebuah ekosistem, dan bergantung pada hal-hal yang tidak pernah secara eksplisit kita sepakati untuk berinteraksi dengannya, sekaligus juga menjadi tempat bergantung bagi hal-hal itu. Kita bisa mengurangi permukaan API dan mencegah semua detail implementasi menjadi urusan tetangga, tetapi keterikatan yang tidak disengaja adalah hukum semesta yang nyaris tak terelakkan seperti bertambahnya entropi
Bagi sebagian orang, ini terdengar nihilistis dan defeatist. Mereka mungkin berkata kita harus melawan entropi. Tetapi menurut saya, penggunaan waktu terbaik dan hasil terbesar dari investasi datang dari mengakui bahwa ini pada dasarnya bukan sesuatu yang harus dilawan, melainkan dikelola
Jika Anda menganggap bahwa Anda selalu bisa mengetahui keadaan dunia, Anda pada dasarnya sedang menjadwalkan kegagalan dan menyalahkan diri sendiri. Sama seperti uptime 100% tidak ada dan merupakan sasaran yang keliru untuk kebanyakan hal
Jika kita mengakui bahwa kita sedang mengelola proses dengan tingkat ketidakpastian ala Heisenberg, kita bisa memilih cara menggunakan waktu terbatas dalam sehari secara efektif untuk menghasilkan hasil yang lebih baik. Terutama, kita jadi bisa membuat kompromi yang cerdas antara respons proaktif dan reaktif, serta memahami bahwa respons reaktif tidak bisa dibuat menjadi 0, dan kadang tidak masuk akal melakukan pencegahan setahun penuh hanya untuk menghindari satu hari respons reaktif
Jadi, seberapa banyak dokumentasi yang harus ditulis di commit? Berapa banyak design doc atau rencana pengujian yang seharusnya ada? Saya juga tidak tahu. Kalau harus melempar satu opsi, semua dokumen ditulis untuk pembacanya
Jika Anda mengubah codebase, anggota tim saat ini, termasuk orang baru yang bergabung nanti, harus bisa memahami melalui penelusuran apa yang dilakukan perubahan itu dan mengapa dilakukan, dan juga harus ada beberapa peringatan tentang pijakan berbahaya atau bug penyangga beban
Ini biasanya bukan berarti prosa panjang, melainkan pointer menuju konteks tambahan yang membantu menyiapkan panggung. Misalnya: “Langkah ini memerlukan autentikasi sebagai bagian dari kebijakan yang mewajibkan persetujuan multipihak untuk semua perubahan. see: go/multiparty”
Sistem yang mengejar kesempurnaan saat berurusan dengan manusia benar-benar tidak nyaman. Seperti DRM, trusted computing, remote attestation, Faro Plague, dan smart contracts
Jauh lebih baik memiliki sistem yang bisa diperbaiki dengan reboot ke service mode. Karena kita tidak bisa memprediksi ke arah mana software harus berevolusi agar benar-benar membantu manusia di masa depan. Lebih baik membuatnya mudah diperbaiki daripada menguncinya 100% rapat
Kami hampir tidak pernah menulis body commit, tetapi cukup pandai menulis judulnya. Jika itu ukuran yang dipakai, saya tidak yakin sebenarnya itu mengukur apa
Dalam codebase besar, kode yang jelas dan test coverage yang memadai sering kali jauh lebih berguna daripada dokumentasi
Ada kasus ketika perubahan yang sepenuhnya valid dilakukan dan test juga diperbarui sesuai itu, tetapi belakangan sama sekali tidak jelas mengapa perubahan tersebut diperlukan. Terutama jika baris yang berubah menimbulkan perilaku tak terduga atau perilaku tambahan di lingkungan produksi
Revert sederhana mungkin bukan pilihan yang diinginkan, dan pada saat seperti ini sangat membantu jika ada riwayat lengkap tentang mengapa perubahan itu dilakukan
Saya sudah sering melihat kasus ketika idenya benar tetapi menghasilkan konsekuensi tak terduga. Jika kita tahu niatnya, kita bisa menemukan perubahan yang benar-benar tepat yang juga memperbaiki masalah baru sambil tetap mempertahankan alasan awal perubahan itu
Jika Anda bersikeras commit satu baris saja, setidaknya sertakan nomor tiket supaya riwayatnya bisa dibaca dari sana
Saya menghasilkan uang yang lumayan selama 5 tahun dengan berkeliling ke berbagai wilayah eksotis untuk memulihkan codebase seperti ini. @arp242, selalu naikkan tarif Anda dan tidurlah dengan https://archive.org/details/working-effectively-with-legacy-code di bawah bantal
Untungnya, generator sampah AI menuliskan pesan commit yang sangat panjang. Sering kali isinya juga agak berkaitan dengan perubahan yang sebenarnya, jadi setidaknya bagian itu bisa dibilang sudah teratasi