Menulis kode yang mudah dihapus
- Setiap baris kode membawa biaya pemeliharaan. Penggunaan ulang kode membuat perubahan menjadi lebih sulit.
- Semakin banyak konsumen API, semakin banyak kode yang harus ditulis ulang saat melakukan perubahan.
- Mengelola dependensi kode adalah masalah penting dalam sistem berskala besar.
Tahap 0: Tidak menulis kode
- Jumlah baris kode sendiri tidak memberikan banyak informasi.
- Kode yang tidak ditulis adalah kode yang paling mudah dihapus.
Tahap 1: Salin-tempel kode
- Kode yang dapat digunakan ulang nantinya bisa ditulis lebih mudah melalui contoh.
- Salin-tempel kode adalah cara untuk menghindari dependensi dan memperoleh fleksibilitas.
Tahap 2: Jangan salin-tempel kode
- Jika kode sudah cukup sering disalin-tempel, inilah saatnya mengekstraknya menjadi fungsi.
- Membuat direktori
util untuk menyimpan beragam utilitas di file lain adalah pendekatan yang baik.
Tahap 3: Tulis lebih banyak boilerplate
- Boilerplate mirip dengan salin-tempel kode, tetapi kode diubah di lokasi yang berbeda-beda.
- Boilerplate mengurangi dependensi dan memberikan fleksibilitas.
Tahap 4: Jangan menulis boilerplate
- Jika boilerplate terlalu banyak, itu perlu dibungkus dengan library yang memiliki pendapat tentang kebijakan, alur kerja, dan status.
- Hubungan antara
requests dan urllib3 adalah contoh yang baik.
Tahap 5: Tulis bongkahan kode besar
- Logika bisnis dicirikan oleh kasus pengecualian yang tak ada habisnya dan hack cepat yang kotor.
- Menghapus satu kesalahan besar lebih mudah daripada menghapus banyak kesalahan kecil.
Tahap 6: Pecah kode menjadi bagian-bagian
- Bongkahan kode besar memiliki biaya pemeliharaan yang tinggi.
- Tanggung jawab kode harus dipisahkan, dan modul perlu dirancang dengan mempertimbangkan kemungkinan perubahan.
Tahap 7: Terus menulis kode
- Harus memungkinkan menulis kode baru secara terpisah dari kode yang sudah ada agar ide-ide baru bisa diuji.
- Feature flag adalah cara untuk bisa berubah pikiran nanti.
Ringkasan GN⁺
- Artikel ini menjelaskan cara membuat kode yang mudah dihapus saat menulis kode.
- Intinya adalah mengurangi dependensi kode, meningkatkan fleksibilitas, dan menurunkan biaya pemeliharaan.
- Proyek dengan fungsi serupa antara lain
requests dan urllib3.
- Artikel ini mengingatkan pengembang perangkat lunak akan pentingnya pengelolaan kode dan pemeliharaan.
1 komentar
Komentar Hacker News
Saya suka ungkapan "Simple is robust". Artinya, semakin rendah kompleksitas sistem, semakin mudah sistem itu diubah. Perencanaan untuk masa depan sebaiknya dibangun dengan kode yang intuitif, bukan kode yang dapat diskalakan. Misalnya, lakukan abstraksi hanya saat situasi memang menuntutnya, anjurkan duplikasi sederhana, gunakan monolit pada tahap awal, dan utamakan penskalaan vertikal daripada horizontal. Setelah membangun beberapa sistem 0-1, saya menemukan kesamaan-kesamaan ini.
Saya heran tidak ada pembahasan tentang testing atau observabilitas. Testing memang punya biaya pemeliharaan, tetapi mengurangi risiko masalah saat menghapus kode. Saat mengekspos layanan ke pemanggil eksternal, perlu ada cara yang kuat untuk menandai sebagian panggilan sebagai akan dihentikan dan mengamati apakah panggilan itu masih digunakan. Baru-baru ini saya menghapus resolver GraphQL secara semi-otomatis, dan melalui metrik frekuensi penggunaan saya bisa mengetahui resolver mana yang tidak bisa dihapus. GraphQL punya anotasi deprecation, tetapi kami tidak secara khusus menanganinya di layanan. Dengan menambahkan observabilitas untuk mengatur flag saat fungsi yang ditandai deprecated dipanggil, lalu menjalankannya di production cukup lama, kita bisa menghapus kode yang terekspos ke luar dengan aman.
Saya jadi sering mempromosikan "desain untuk penghapusan". Dulu saya berpikir saya bisa merencanakan semua situasi dan membuat karya yang memenuhi semua kebutuhan, tetapi kebutuhan masa depan sulit diprediksi. Pada suatu hari, apa yang saya buat akan menjadi tidak berguna bagi seseorang, dan akan masuk akal bila mereka membongkarnya. Karena itu, kita harus berupaya membuatnya mudah dihapus. Ini sering menghasilkan coupling yang lebih rendah, tetapi berbeda dari pendekatan pengembang muda yang ingin memisahkan segalanya ke dalam framework meta yang bisa dikonfigurasi. Terkadang coupling yang erat justru lebih baik jika secara logis lebih mudah dipahami.
Untuk menulis kode yang mudah dihapus, lakukan pengulangan untuk menghindari dependensi, bukan pengulangan untuk mengelolanya. Bagi kode ke dalam beberapa lapisan, dan bangun API sederhana di atas bagian yang sederhana untuk diimplementasikan tetapi tidak nyaman dipakai. Pisahkan kode, dan saling pisahkan bagian yang sulit ditulis serta bagian yang kemungkinan besar akan berubah dari sisa kode. Jangan hardcode semua pilihan; buat agar beberapa hal bisa diubah saat runtime. Berdasarkan pengalaman pribadi, kode yang mudah dihapus biasanya berlapis dan termodularisasi, sehingga juga mudah diperluas.
Saya selalu mengatakan kepada mahasiswa fisika komputasi bahwa komputasi terbaik adalah yang tidak perlu dipikirkan.
Secara pribadi saya membagi kode menjadi logika bisnis dan implementasi aktual. Logika bisnis, karena sifatnya, bisa saja terduplikasi, tetapi terlalu banyak detail teknis tidak seharusnya diduplikasi. Selama logika bisnis tidak ditangani secara langsung dan tetap independen dari aplikasi, logika bisnis itu boleh saja berantakan sesuka hati. Jika terjadi masalah dan hasilnya tidak baik, selalu ada opsi untuk menghapus seluruh implementasi, memperbaikinya, dan tidak dipaksa mencari spesifikasi sebenarnya dari dalam implementasi.
Kesalahan yang jelas di paragraf pertama: masalah dengan penggunaan ulang kode adalah bahwa hal itu menghalangi Anda untuk berubah pikiran nanti. Ini umumnya klaim yang salah. Jika Anda berubah pikiran dan kodenya telah disalin-tempel ke sepuluh tempat, Anda harus mengubah sepuluh tempat itu. Sebaliknya, jika kodenya ada di dalam sebuah fungsi, Anda hanya perlu mengubahnya sekali. Jika satu dari sepuluh pemanggilan itu memang tidak boleh berubah, Anda tetap bisa menyalin-tempelkannya, dan Anda juga bisa membuat fungsi itu lebih umum. Seperti tidak melihat kanan-kiri saat menyeberang jalan, salin-tempel hampir selalu merupakan ide yang buruk.
Ada korelasi yang sangat kuat bahwa kode buruk bertahan lama karena sulit dihilangkan.
Saya penasaran apakah maksudnya adalah menggunakan software sedekat mungkin dengan keadaan default-nya dan tidak melakukan kustomisasi secara mendalam.