- Struktur atau kode yang awalnya tampak sepele atau sementara dapat seiring waktu mengambil peran menopang sistem, sehingga sebelum mengubahnya kita perlu memeriksa hubungan ketergantungan yang ada saat ini
- Chesterton's Fence adalah prinsip yang berguna: pahami alasan pemasangannya sebelum menghapusnya, tetapi jika hanya melihat niat awalnya kita bisa melewatkan peran yang muncul belakangan
- Saat renovasi kamar mandi rumah, sebuah stud vertikal yang tampak seperti penghalang ternyata setelah fungsi sekat lemari tak lagi dibutuhkan justru ikut menopang sebagian beban lantai dua karena perubahan struktur yang keliru
- Dalam sistem komputer yang kompleks, riwayat perubahan dan dokumen desain hanyalah titik awal; kita juga harus melihat bagaimana sebuah komponen terintegrasi ke dalam sistem saat ini
- Saat menghapus atau memodifikasi komponen lama, jika kita tidak memeriksa sekaligus alasan desain masa lalu dan peran tersembunyi yang dimilikinya sekarang, kita bisa memicu gangguan yang tak terduga
Apa yang Bisa Terlewat oleh Chesterton's Fence
- Chesterton's Fence adalah gagasan bahwa sebelum mengubah atau menghapus sesuatu, kita harus lebih dulu mengetahui mengapa benda itu dibuat
- Sesuatu yang dibuat manusia, seperti pagar atau pintu, umumnya kemungkinan besar ada karena pernah dianggap bermanfaat bagi seseorang
- Bahkan desain yang tampak sepenuhnya tak bermakna pun bisa jadi menyimpan sisi persoalan yang terlewat oleh orang yang ingin mengubahnya
- Namun sudut pandang ini bisa membuat kita hanya fokus pada peran yang dimaksudkan pembuat aslinya, sehingga mengabaikan ketergantungan baru yang muncul kemudian
Penopang Beban yang Ditemukan Tak Sengaja Saat Renovasi Rumah
- Beberapa tahun lalu, saat merenovasi ulang kamar mandi rumah, ada sebuah stud vertikal yang mengganggu pekerjaan
- Stud itu awalnya merupakan bagian dari sekat lemari, dan fungsi sekat lemari tersebut tampaknya sudah tidak diperlukan lagi
- Jika hanya mengikuti sudut pandang Chesterton's Fence, menghapusnya tampak aman, tetapi kenyataannya seiring waktu ia telah menjadi struktur penopang beban
- Melalui perubahan struktur lain yang keliru, stud ini ikut berkontribusi menopang lantai dua rumah
- Kita perlu memeriksa bukan hanya alasan sesuatu dibuat pada awalnya, tetapi juga peran tambahan apa yang kemudian diembannya
Pelajaran yang Berlaku untuk Sistem Komputer Kompleks
- Masalah yang sama berulang juga ketika mengubah sistem komputer yang kompleks
- Meninjau riwayat perubahan, membaca dokumen desain awal, dan memahami mengapa komponen tertentu dibuat seperti itu tetap berguna
- Namun, agar aman, kita juga harus melihat bagaimana komponen tersebut terhubung dan digunakan di dalam sistem saat ini
- Seiring waktu, komponen mudah mengambil peran tambahan yang berbeda dari tujuan awalnya
- Perubahan yang aman dimulai dari memeriksa bersama-sama niat desain di masa lalu dan peran nyata yang dijalankannya sekarang
1 komentar
Komentar Hacker News
Rasanya akhirnya ada nama untuk menyebut hal ini
Saya banyak menangani dukungan sistem kontrol, dan cukup sering kode PLC yang memperlakukan peralatan fisik dengan cara aneh justru menimbulkan masalah yang tidak disengaja
Saya jadi sering mengulang ungkapan, “setiap kali Anda memperbaiki masalah listrik/mekanik dengan perangkat lunak, lahirlah seekor gremlin”
Bahkan jika saya menemukan akar penyebab bug atau batasan terprogram yang ingin dihapus, saya selalu menolak sampai saya tahu mengapa kode itu ada. Tidak ada kode yang masuk tanpa alasan, jadi saya harus memahami dulu mengapa timer atau override itu diperlukan
Kadang itu kabar baik jika ternyata kodenya dibuat untuk mengatasi masalah yang sekarang sudah hilang, tetapi sering juga itu adalah kode yang ditambahkan untuk mencegah suatu insiden dan tujuan aslinya hilang karena pergantian personel. Tanpa dokumentasi, saya jadi sangat berhati-hati untuk langsung membalikkan pekerjaan orang lain
Ada juga unsur kepercayaan pada rekan kerja. Biasanya orang tidak melakukan sesuatu tanpa alasan, jadi kalau ada kode, saya harus berasumsi ada tujuannya dan percaya bahwa pada awalnya itu sudah ditinjau dengan cukup matang. Jika kepercayaan itu runtuh, semua pengambilan keputusan jadi sulit
Jika alasannya adalah interaksi dengan hal-hal di luar codebase seperti sistem operasi, file system, database, endpoint HTTP, atau hardware, saya 100% akan memberi komentar, kecuali itu hanya pemanggilan API atau library yang sederhana
Jika saya menambahkan
sleepkarena rate limit layanan lain, saya tulis siapa yang meminta itu, nilai batas yang diketahui saat itu, kalau tidak tahu persis saya tulis “ini perkiraan, tapi tampaknya bekerja”, dan bagaimana sistem bisa terlihat jika batas itu terlampauiJika saya memakai database untuk sesuatu yang kelihatannya sepele dan mestinya bisa memakai file system, tetapi pada kenyataannya akses ke file system dengan cara yang dibutuhkan di lingkungan itu menyebabkan system call tak terkendali saat beban tinggi hingga sumber daya habis, saya tulis komentarnya
Workaround untuk bug library yang banyak dipakai dan tidak diperbaiki Ubuntu di rilis LTS juga layak diberi komentar. Saya sangat sering menulis komentar seperti, “saya tahu ini jelek, tapi inilah alasannya”
Bahkan saat saya menulis kode yang tidak akan berjalan baik pada skala besar karena malas membuatnya scalable sekarang, dan menurut perkiraan saat ini memang belum diperlukan, saya tetap beri komentar. Mungkin ini lebih untuk menjaga harga diri, tetapi bentuknya seperti, “saya tahu ini membaca seluruh file ke memori, tetapi ini pekerjaan batch yang jarang dan bisa diprediksi, dan filenya akan kecil, jadi tidak apa-apa. Jika memori habis, mulai periksa dari sini. Kalau mau mengubahnya menjadi pemanggilan on-demand, tulis ulang saja”
Poin yang ingin disorot tulisan itu adalah bahwa itu sendiri belum cukup. Anda juga harus tahu apa lagi yang dibangun di atas asumsi bahwa kode itu ada
“Saya tidak tahu mengapa rung ini diperlukan, tapi coba hapus lalu buktikan sendiri”
Saya tidak menyentuhnya, dan juga tidak mencoba membuktikannya
Insinyur elektro dan mekanik secara historis memandang perangkat lunak kurang serius dibanding sistem listrik dan mekanik, dan akibatnya di budaya engineering yang didominasi EE/ME, kode berantakan lebih mudah muncul
Bahkan di antara orang-orang yang secara formal berstatus Professional Engineer, software engineering yang terlalu mentah untuk bisa diterima masih umum ditemukan
Lupakan kode tanpa dokumentasi; biasanya hardwarenya pun adalah barang kustom buatan 30 tahun lalu, jadi bahkan diagram rangkaian dari peralatan yang sedang dikerjakan pun tidak ada
Saya pernah mengalami hal serupa
Beberapa tahun lalu saya membeli rumah tua, dan pemilik-pemilik sebelumnya tampaknya melakukan sendiri sebagian besar pekerjaan sejak tahun 1960-an
Talang seng mungkin sudah bocor selama puluhan tahun dan merusak sebagian struktur atap, lalu atap itu ditopang oleh panel kayu yang dipasang pada tahun 70-an untuk menutup bagian dalam. Jadi panel kayu itu benar-benar sedang menanggung beban
Saya menemukan jauh lebih banyak hal seperti itu di rumah ini. Misalnya, ketika lebar genteng di ujung atap kurang, alih-alih membeli genteng tambahan, mereka menutupinya dengan semen dan pecahan pot keramik
Sekarang peran itu kita bebankan pada drywall dan plywood saat menghadapi gempa dan badai
Jika Anda melihat rumah yang dibangun ulang hingga hanya tinggal rangkanya, Anda akan melihat beberapa penguat tambahan. Itu bukan untuk mencegah dinding roboh, tetapi untuk mempertahankan siku dan kerataan bidang sampai dindingnya dibangun kembali
Sekilas tampak seperti seseorang menabrak pintu garasi dan membuatnya penyok parah, tetapi setelah dilihat lebih dekat, ternyata atapnya nyaris bertahan di rel tempat pintu terpasang dan hampir benar-benar ambruk
Awalnya saya ingin hanya mengganti pintu garasi dengan menyambung ujung kasau, karena dulu seseorang tampaknya melakukan hal yang sama di sisi seberang dan itu berhasil, tetapi sekarang sepertinya saya harus mengganti seluruh atap
Yang benar-benar mengkhawatirkan adalah kabel mencurigakan yang membentang di seluruh basement. Ada campuran kabel yang relatif baru, kabel tua berlapis kain, dan sambungan dengan isolasi listrik yang ditempelkan di atasnya. Untungnya tampaknya tidak ada kabel yang ikut menanggung beban
Sepertinya tulisan ini dan hampir semua komentarnya melewatkan masalah yang sebenarnya. Intinya adalah kurangnya pengujian
Tidak seperti semua alat produksi lainnya, perangkat lunak bisa benar-benar menguji perubahan sebelum diterapkan ke dunia nyata
Jika ada pengujian yang baik, tidak penting apa niat awalnya, atau apakah fungsi itu mendapatkan kegunaan baru atau pengguna baru. Perbaiki lalu jalankan pengujian, dan hasilnya akan memberi tahu apakah perbaikan itu bagus
Jika ada pengujian yang baik, Anda tidak memerlukan arkeologi perangkat lunak, veteran kawakan yang tahu semua retakan, jenius yang memodelkan sistem kompleks di kepalanya, dokumen kebutuhan yang menyeluruh, atau sistem rilis hati-hati yang menjadikan sebagian kelompok pengguna sebagai kelinci percobaan
Jika ada pengujian yang baik, Anda bahkan bisa mengubah sistem secara acak lalu berhenti saat ada peningkatan. Tepat seperti cara Google melaporkan bahwa AI “mengembangkan” perbaikan ranking
Meski begitu, pengembang pengujian dibayar kurang dari separuh, departemen pengujian relatif kecil, QA terdesak oleh jadwal yang tetap dan terbatas, dan hampir tidak ada pahlawan teknis yang berasal dari QA. Mungkin karena pekerjaan ini terlihat turunan dan reaktif
Anda mungkin menghapus kode yang tidak dipakai beserta pengujiannya, padahal ternyata sebenarnya masih digunakan
Setelah perubahan, pengujian gagal, tetapi karena pengujiannya rapuh Anda menyesuaikannya dengan situasi baru—lalu ternyata ada sesuatu yang bergantung pada perilaku lama
Pengujian itu luar biasa, dan dalam sistem yang cukup mandiri itu mungkin sudah cukup. Tetapi dalam sistem yang lebih besar, kadang telemetri atau rollout bertahap juga diperlukan
Awalnya kode itu dibuat untuk menghitung VAT pada daftar pembelian, tetapi lambat laun bisa menjadi sarana untuk memaksa refresh cache VAT per kategori produk dan dipanggil dalam konteks yang tidak pernah diperkirakan semula
Hal yang sama berlaku untuk komentar. Komentar membahas niat awal dan efek samping, tetapi tidak bisa membahas di mana metode atau kelas itu dipakai jauh di kemudian hari, atau sebenarnya menjadi melakukan apa
Di dunia ideal, komentar juga diperbarui saat dunia di sekitarnya berubah, tetapi dalam praktiknya hampir tidak pernah begitu kecuali kode internalnya ikut berubah
Biasanya pengujian membusuk. Seolah-olah pengujian juga punya masa kedaluwarsa, dan pada akhirnya sebagian pengujian mulai mati
Masalah dependensi, perubahan ekspektasi API, pembaruan keamanan, akun dan kredensial yang kedaluwarsa, perubahan endpoint dan state mesin—semuanya bercampur sehingga hasil pengujian tidak lagi menunjukkan kebenaran program
Nilai bisnis marginal untuk memperbaiki satu pengujian yang rusak biasanya sangat rendah, jadi sering kali pengujian itu dimatikan begitu saja atau dipaksa “lulus” padahal seharusnya error
Setelah 10 atau 20 tahun berulang seperti itu, dengan cepat akan terbentuk perbedaan antara “pengujian yang benar-benar dipercaya” dan “pengujian yang terlalu sibuk untuk diperbaiki atau dibersihkan”
Pengetahuan kesukuan tentang pengujian mana yang baik dan mana yang buruk menghilang seiring pergantian pekerjaan dan peran, dan pada satu titik gumpalan “pengujian yang berbohong dengan mengatakan semuanya berjalan” dan “pengujian yang kegagalannya tidak lagi diperiksa apakah benar” itu sendiri secara tidak sengaja mulai menanggung beban
Lebih baik sekalian bilang bahwa programmer harus menulis pengujian, menyimpannya bersama kode, dan menjalankannya secara otomatis dalam proses build
Namun menurut saya, bahkan test-driven development yang dilakukan dengan benar pun tidak bisa menggantikan desain yang baik dan praktik yang baik. Bahkan spesifikasi yang sangat sederhana pun tidak bisa digantikan oleh pengujian
Jika hanya dispesifikasikan bahwa
f(S)mengembalikan string yang digabungkan dengan dirinya sendiri, maka sulit memverifikasi bahwafitu benar hanya dengan pengujian yang jelas-jelas memperlakukanfsebagai black box. Spesifikasi formal juga pentingAnda bisa mencoba di beberapa titik, tetapi jika ada satu nilai salah yang secara ajaib bisa berakibat fatal, pengujian tidak akan menunjukkannya
Arkeologi perangkat lunak, veteran kawakan, jenius yang memodelkan sistem di kepala, dokumen kebutuhan yang komprehensif, dan sistem rilis yang menjadikan sebagian pengguna sebagai kelinci percobaan mungkin bisa disindir, tetapi semuanya adalah respons yang muncul karena perangkat lunak itu sulit. Dan perangkat lunak memang benar-benar sulit
Biasanya tim perangkat lunak harus bertanggung jawab langsung atas kualitas pekerjaan mereka sendiri, dan tidak bisa melempar masalah melampaui batas organisasi
Saya paham bahwa stud yang tadinya tidak penting kemudian menanggung beban, tetapi menurut pengalaman saya ini terlihat seperti tanda desain yang malas
Setidaknya saat membuat perangkat lunak, Anda bisa tahu bahwa Anda sedang mencoba menopang sebagian rumah dengan stud dekoratif, dan jika Anda memilih membiarkannya begitu saja alih-alih membuat struktur baru yang lebih baik, tim pengembang akan cukup menderita nantinya
Saya setuju dengan tulisan ini, tetapi jauh lebih baik bekerja di tempat yang memungkinkan kita berharap tidak terlalu sering menemukan hal seperti ini
Poin tulisan ini bukan bahwa Anda tidak boleh memakai stud dekoratif sebagai elemen penyangga beban, melainkan lebih ke menyadari bahwa sebelum Anda datang, seseorang mungkin sudah melakukannya
Ini adalah sikap yang bahkan lebih konservatif daripada tafsir dasar Chesterton's Fence, dan bahkan tafsir dasar itu sendiri sering disingkirkan banyak orang karena dianggap terlalu membatasi
Bagi saya tulisan ini terasa relevan. Dalam istilah pemrograman, saya pernah benar-benar mengalami menghapus molding yang “dekoratif” lalu langit-langit runtuh di atas kepala saya
Apakah sebuah sistem kokoh, atau justru berbahaya karena tidak bisa diskalakan, bergantung pada konteksnya
Kita selalu bisa melakukan eksperimen pikiran seperti, “Bagaimana kalau tim sales jadi dua kali lebih besar dan kita harus menjual serta melakukan onboarding pelanggan secepat mungkin sampai menguasai 100% pasar?” dan dalam kondisi seperti itu, mungkin saja memakai database sebagai message queue tetap masuk akal
Jika akibatnya tim pengembang jadi sengsara, itu berarti sebuah kesalahan. Sistemnya jadi sulit dirawat atau berubah menjadi neraka operasional
Tetapi memakai stud dekoratif perangkat lunak sebagai elemen penyangga beban tidak selalu berujung seperti itu. Ada banyak sistem yang diam-diam menjalankan tugasnya dengan baik, sambil menghemat berbulan-bulan waktu yang dibutuhkan untuk membuat solusi yang “benar”
Sisa codebase tidak akan pernah mengirim input yang salah, jadi cabang itu adalah dead code dan tidak menanggung beban
Lalu pada suatu titik ada bug yang masuk dan mengirim input salah, dan cabang itu dengan setia menanganinya lalu memulihkan keadaan. Pada saat itu, cabang tersebut menjadi cabang penyangga beban
Salah satu artefak “yang tanpa sengaja menanggung beban” favorit saya adalah konfigurasi
sudoyang salahIa mengizinkan
sudotanpa kata sandi untuk perintahfind, sehingga eksekusi kode arbitrer dengan hak root lewat-execjadi sangat mudah, dan beberapa skrip dukungan penting produk ternyata ditulis untuk memanfaatkan ituBisa dibilang ini adalah eskalasi hak akses yang menanggung beban
Beberapa tahun lalu saya merenovasi dapur
Di salah satu ujung dapur lama ada balok besar melintang, yang ditambahkan dalam renovasi sebelum kami membeli rumah untuk menopang penambahan lantai dua. Untuk memperluas dapur, balok ini harus disingkirkan
Setelah plafon dibuka, ternyata balok itu berada sekitar 2 kaki di sebelah kanan dari posisi yang seharusnya untuk menopang dinding lantai atas
Akhirnya kami memperbaikinya dan memindahkan balok itu ke dalam dinding lantai atas, dan semuanya beres, tetapi ketika saya bertanya tentang posisi aslinya, kontraktornya mengatakan kurang lebih begini
“Ada satu orang yang ingin mengerjakannya dengan benar, dan satu orang yang tidak peduli. Pada akhirnya kualitas akan mengikuti setelan terendah”
Salah satu hal yang membuat perangkat lunak lebih baik daripada sistem fisik adalah, kita bisa lebih mudah mendokumentasikan niat dengan lebih jelas di dalam kode lewat komentar dan tipe
Terutama dalam bahasa dinamis seperti Python, ini memang tidak sempurna, tetapi sangat membantu
Analogi untuk stud penyangga beban itu bisa jadi proyek hackathon yang awalnya tak pernah disangka akan masuk produksi
Kenyataannya, banyak dari pekerjaan kita memang hanya mengutak-atik sesuatu sampai nyaris bisa jalan, lalu lanjut ke hal berikutnya
Rencana pemeliharaan harus mengetahui “beban” apa yang ditanggung setiap komponen atau rakitan yang bisa diganti
Sayangnya, rekayasa sistem masa kini sudah sangat jauh melenceng dari tujuan awal itu, tetapi konsep awalnya memang demikian
Salah satu alasan departemen rekayasa sistem sekarang relatif kurang berpengaruh adalah karena urusan keuangan ikut masuk ke perencanaan pemeliharaan. Depresiasi inventaris itu kejam, dan soal “apa yang harus disimpan sebagai suku cadang” setidaknya dalam pengalaman saya, sekarang jarang menjadi keputusan rekayasa sistem
Hasilnya bisa ditebak, tetapi ini sedikit diimbangi oleh fakta bahwa standar teknisi perawatan dirgantara sangat tinggi. Dibandingkan, misalnya, teknisi servis mesin cuci, mereka jauh lebih unggul
Tentu saja, bagian keuangan juga ingin menurunkan standar itu beberapa tingkat
Tapi saya selalu terkejut melihat betapa seringnya sistem yang komponen hulunya tampak “dekoratif” ternyata sebenarnya berfungsi sebagai pembatas laju, sehingga ketika dihapus, sisanya malah lepas kendali
Ini mengingatkan saya pada kasus ketika pengguna tanpa sadar memanfaatkan bug perangkat lunak lalu memasukkannya ke alur kerja normal mereka
Akibatnya, ketika bug itu diperbaiki, alur kerja mereka rusak dan muncullah keluhan
Dikatakan, “Mudah mengetahui mengapa itu ada di sana. Itu bagian dari sekat lemari,” tetapi seiring waktu ia kebetulan mulai menanggung beban, dan melalui perubahan struktural lain yang keliru, stud itu kini membantu menopang lantai dua rumah
Tetapi jelas sebenarnya tidak mudah mengetahui mengapa itu ada di sana. Selain itu, saya juga tidak terlalu yakin bahwa ia kebetulan mulai menanggung beban
Walaupun bagi Anda alasannya tampak salah, cukup mungkin bahwa pada saat itu orang-orang memang dengan sengaja menjadikannya penyangga beban karena alasan yang bagi mereka masuk akal
Hanya saja, mengetahui kenapa awalnya itu ada di sana tidak memberi tahu kita apa yang sekarang sedang dilakukannya
Dulu seorang postdoc fisika yang pernah bekerja dengan saya kadang menempelkan tanda seperti ini di atas susunan peralatan
“Jangan disentuh. Ada bahaya tersembunyi”
Laboratorium itu penuh orang pintar, dan mereka terbiasa melihat sesuatu lalu menyimpulkan sendiri secara rasional apakah itu aman untuk diubah
Tanda ini adalah sebuah peringatan agar mereka tidak terlalu cepat mengambil keputusan seperti itu