Saya mendapat kesan, bahwa monkeypatching lebih dalam kategori hack cepat dan kotor, daripada praktik pemrograman standar yang baik. Sementara saya telah menggunakan dari waktu ke waktu untuk memperbaiki masalah kecil dengan lib pihak ke-3, saya menganggap itu perbaikan sementara dan saya akan mengirimkan tambalan yang tepat untuk proyek pihak ke-3.
Namun, saya telah melihat teknik ini digunakan sebagai "cara normal" dalam proyek-proyek utama, misalnya dalam gevent.monkey
modul Gevent .
Apakah monkeypatching menjadi arus utama, normal, praktik pemrograman yang dapat diterima?
Lihat juga: "Monkeypatching For Humans" oleh Jeff Atwood
Jawaban:
Tidak, tapi terkadang monkeypatch adalah kejahatan yang lebih kecil (daripada memiliki kode yang rusak :)). Aturan umum saya untuk monkeipatch di ruby adalah:
memiliki alasan yang sangat bagus untuk monkey-patch (perbaikan terbaru sementara yang kritis adalah alasan yang bagus. Pemformatan yang bagus dari metode to_s tidak, kecuali jika Anda sedang mengerjakan ActiveSupport)
buatlah setransparan mungkin: letakkan di tempat tertentu dalam basis kode dan pisahkan file, tulis dokumentasi yang menjelaskan alasan monkeypatch (inilah contohnya ).
mudah dihapus - dokumentasi harus menyertakan info tentang penghapusan dan apa yang harus diperhatikan. Banyak monkeypatch bersifat sementara, sehingga mudah dihapus.
sumber
Ya, monkeypatching sangat berguna!
Entah bagaimana, nama tampaknya sangat berpengaruh pada persepsi orang. Sebut saja "monkeypatch" dan kedengarannya buruk, sebut saja "hot fix" atau "on-the-fly fix" dan kedengarannya bagus.
Terlepas dari itu, saya pikir kemampuan untuk mengubah metode / atribut / fungsi saat runtime adalah hal yang sangat berguna. Bahkan orang javascript menggunakannya sepanjang hari tanpa mungkin menyadarinya.
Contohnya:
Baris sederhana ini menggambarkan fakta bahwa Anda mengubah perilaku tombol. Itu dirancang seperti itu. Demikian juga, Anda dapat mengubah setiap fungsi lain tetapi itu konyol untuk melakukannya.
Sekarang, untuk pertanyaan tentang pengiriman tambalan seperti itu ... yah ... mengapa tidak. Anda hanya perlu mengunduh tambalan kecil alih-alih rilis besar. Heck, Anda bahkan bisa menambal server tanpa menghentikannya, bagus! Dan kemudian, suatu hari, Anda juga bisa mengambil rilis terbaru untuk pembaruan yang lebih besar. Cukup adil. Jadi ya, saya memilih "runtime patches" sebagai hal yang baik.
Yang cukup menarik, beberapa bahasa seperti Erlang bahkan dibangun di sekitar konsep ini. Kemampuan untuk memperbarui server dengan cepat.
Tentu saja, pada akhirnya, dan suka dengan yang lainnya, itu masalah bagaimana Anda menggunakannya. Anda dapat membuat barang-barang OO yang bagus dan menyebalkan, semuanya sama saja.
EDIT:
Izinkan saya menambahkan beberapa perbedaan huruf besar, baik Anda menambal perpustakaan Anda sendiri atau perpustakaan pihak ketiga .
... pada dasarnya, apa yang Anda lakukan dengan tambalan itu adalah memperbaiki bug Anda sendiri atau pustaka pihak ketiga . Dalam kedua kasus itu berguna. Untuk Anda sendiri, ini memungkinkan Anda mengirimkan perbaikan saat bepergian. Untuk pihak ketiga, Anda menunggu (beberapa bulan?) Sampai mereka memperbaikinya sendiri, atau Anda melakukannya sendiri. (Anda masih bisa mengirimkan mereka tambalan, sehingga mereka akan memperbaikinya di sisi mereka). Ketika mereka merilis versi lib berikutnya dengan masalah diperbaiki, Anda masih bisa, jika Anda ingin memperbarui perpustakaan dan menghapus tambalan di sisi Anda.
Sekarang, tentu saja, jika Anda menggunakan tambalan untuk mengubah perilaku lib dan mengasingkan tujuan / cara kerjanya, maka jelas itu adalah resep untuk bencana. Bahkan seekor monyet akan melihat itu ... well, saya harap. ;)
sumber
Saya percaya bahwa semua tambalan secara inheren berisiko karena sifatnya run-time, dan ketidakmampuan untuk ditangkap pada waktu desain.
Mereka menerima pengecualian runtime, dan membutuhkan debugger dan jam tangan yang kompleks hanya untuk mengikuti.
Mereka digunakan ketika orang kelas SEAL, dan jadi warisan tidak mungkin. Namun, ada cara yang lebih baik untuk memperluas objek tanpa merusaknya.
Dua sen saya
sumber
Menambal secara umum harus menjadi pilihan terakhir, bahkan menambal monyet juga. Masalah ini terutama salah satu dari rawatan.
Beberapa waktu yang lalu, kernel linux saya memiliki 3 tambalan terpisah yang diterapkan padanya, yang diperlukan untuk driver kartu video saya dan dua aplikasi berpemilik yang saya miliki. Dua dari mereka memiliki perubahan yang saling bertentangan, yang berarti saya membutuhkan tambalan ke-4 untuk menyelesaikan perbedaan di antara mereka. Sekarang setiap kali masalah keamanan diperbaiki di kernel hulu, saya juga harus menunggu vendor dari 3 patch untuk merilis pembaruan ke versi kernel baru, yang memakan waktu dari satu hingga enam bulan, atau saya harus secara manual mempertahankan upstream patch keamanan sampai vendor patch lain menyusul.
Setelah beberapa tahun, para vendor berhasil dimasukkan ke dalam sumber kernel hulu, dan saya dapat menghentikan tindakan penyeimbangan, tetapi Anda dapat melihat kekacauan apa yang terjadi pada saat itu. Jangan lakukan itu pada programmer Anda kecuali Anda harus melakukannya.
sumber
Tidak. Ini bukan teknik standar untuk pengembangan perangkat lunak. Ini masih merupakan solusi untuk menyelesaikan masalah akut dan memiliki kelemahan yang jelas. Pelanggaran Prinsip Substitusi Liskov muncul di benak saya. Penambalan monyet membuatnya lebih sulit untuk berpikir tentang program. Untuk program Anda sendiri, Anda harus menempatkan kode di tempatnya. Untuk lib pihak ketiga Anda akan selalu hidup dalam bahaya, bahwa tambalan Anda tidak akan berfungsi dengan versi lib berikutnya.
Tentu saja tambalan monyet berguna jika Anda tahu apa yang Anda lakukan dan tidak punya waktu untuk menerapkan solusi SOLID . Tetapi Anda tidak boleh menganggap ini sebagai teknik standar dan membangun tambalan monyet di atas tambalan monyet.
BTW, apakah Anda pernah menulis unit test untuk patch monyet?
sumber