Ketika mengembangkan perangkat lunak, saya sering memiliki pustaka 'inti' terpusat yang berisi kode praktis yang dapat dibagikan dan dirujuk oleh berbagai proyek.
Contoh:
- seperangkat fungsi untuk memanipulasi string
- ekspresi reguler yang umum digunakan
- kode penempatan umum
Namun beberapa rekan saya tampaknya berpaling dari pendekatan ini. Mereka memiliki masalah seperti overhead pemeliharaan kode pengujian ulang yang digunakan oleh banyak proyek setelah bug diperbaiki. Sekarang saya mempertimbangkan kembali kapan saya harus melakukan ini.
Apa masalah yang membuat penggunaan pustaka 'inti' menjadi ide yang buruk?
code-reuse
libraries
Alex Angas
sumber
sumber
Jawaban:
Pustaka inti buruk ketika mereka mulai menderita fitur creep, dan sangat buruk ketika mereka tidak terawat dengan baik.
Anda mungkin menemukan artikel ini menarik untuk sudut pandang diperpanjang (yang saya setujui dengan sepenuh hati):
http://www.yosefk.com/blog/redundancy-vs-dependencies-which-is-worse.html
Don Knuth: "Bagi saya, 'kode yang dapat diedit ulang' jauh, jauh lebih baik daripada kotak hitam atau toolkit yang tidak tersentuh ... Anda tidak akan pernah meyakinkan saya bahwa kode yang dapat digunakan kembali sebagian besar bukan ancaman."
sumber
Menggunakan ide perpustakaan inti menjadi buruk ketika beberapa proyek bergantung padanya, seperti mengatakan Anda tidak boleh menggunakan jQuery untuk web, libxml di aplikasi * nix Anda, atau kerangka kerja atau pustaka lainnya. Lihatlah seluruh ekosistem perkembangan modern (KERING, OOP, dll) dan setiap aplikasi dibangun dari sekumpulan perpustakaan dan kerangka kerja.
Apa yang bisa buruk adalah jika Anda tidak memiliki semua jenis unit test, Anda tidak melakukan uji regresi dan Anda tidak menggunakan semua jenis API / ABI dengan perpustakaan Anda. Jika semua aplikasi Anda memiliki tes yang tepat, perpustakaan Anda memiliki pengujian yang tepat, dan Anda memastikan jika Anda melanggar panggilan fungsi Anda memperbarui nomor versi api dengan tepat.
Untuk cakupan lengkap, yang mungkin orang inginkan adalah ketika perubahan dilakukan ke Perpustakaan, Anda dapat menjalankan serangkaian tes yang akan memverifikasi API belum rusak, dan bahwa pelaksanaan semua kode bebas bug. Kemudian Anda dapat menarik pembaruan perpustakaan terbaru ke dalam aplikasi Anda dan menjalankan serangkaian tes yang sama. Jika Anda memperbarui API, maka itu harus didokumentasikan sehingga Anda tahu apa yang perlu Anda lakukan dalam aplikasi Anda untuk memperbaruinya. Either way, ketika Anda menjalankan tes untuk aplikasi Anda, maka Anda dapat menjadi percaya diri seperti Anda dalam tes Anda bahwa tidak ada yang rusak.
Saat menggunakan jquery, mootools, pustaka atau kerangka javascript apa pun, Anda tidak bisa begitu saja menggunakan versi baru, sayangnya Anda bahkan tidak bisa dengan rilis minor 1.6.z kadang-kadang.
sumber
Jika Anda memiliki serangkaian unit test komprehensif untuk perpustakaan inti; itu bukan masalah. Tidak ada kode yang akan diperiksa kecuali semua tes lulus. Jika Anda memperkenalkan cacat Anda menulis tes gagal untuk mereproduksi cacat dan memperbaikinya; maka Anda akan selalu menguji kesalahan itu juga. Selama-lamanya.
Juga fungsionalitas yang Anda gambarkan sangat mudah untuk menulis unit test.
Sebagai masalah tambahan, Anda mungkin ingin memiliki lebih dari satu pustaka inti sehingga Anda tidak harus memasukkan kode RegEx kecuali Anda mau.
sumber
Saya akan menawarkan sedikit berbeda dalam hal ini. Pustaka inti, dalam banyak kasus, adalah ide bagus!
Jika Anda memiliki dua proyek terpisah, mereka harus berada dalam dua repositori kode terpisah. Sekarang mereka bergantung pada fungsi umum. Mari kita pertimbangkan misalnya aplikasi pemrosesan paket. Fungsi umum dapat mencakup:
Sekarang, aplikasi pemrosesan paket yang berbeda mungkin memerlukan subset yang berbeda. Haruskah Anda menerapkan satu pustaka inti dengan satu repositori kode sumber, atau haruskah Anda memiliki 18 repositori berbeda untuk masing-masing modul ini? Ingat bahwa modul-modul ini mungkin memiliki inter-dependensi, jadi sebagian besar modul ini mungkin bergantung pada mis. Modul lain-lain.
Saya akan mengklaim bahwa memiliki satu perpustakaan inti adalah pendekatan terbaik. Ini mengurangi overhead dari banyak repositori kode sumber. Ini mengurangi neraka ketergantungan: versi tertentu dari pengalokasi memori mungkin memerlukan versi tertentu dari modul lain-lain. Dan bagaimana jika Anda ingin pengalokasi memori versi 1.7 tergantung pada 2.5 aneka dan AVL tree versi 1.2 tergantung pada aneka 2.6? Anda mungkin tidak dapat menautkan Miscellaneous 2.5 dan Miscellaneous 2.6 secara bersamaan ke program Anda.
Jadi, lanjutkan dan terapkan struktur berikut:
Saya telah melihat bahwa beralih ke struktur semacam ini dari struktur:
Telah menyebabkan berkurangnya pemeliharaan dan peningkatan pembagian kode melalui mekanisme non-copypaste.
Saya juga melihat proyek menggunakan struktur berikut:
... dan neraka ketergantungan dan proliferasi jumlah repositori telah menjadi masalah nyata.
Sekarang, haruskah Anda menggunakan pustaka sumber terbuka yang ada alih-alih menulis pustaka Anda sendiri? Anda perlu mempertimbangkan:
Saya biasanya menggunakan aturan bahwa semuanya di bawah 1000 baris kode yang tidak memerlukan sesuatu di luar keahlian programmer harus diimplementasikan sendiri. Catatan: 1000 baris termasuk unit test. Jadi saya tentu tidak akan menganjurkan menulis 1000 baris kode sendiri jika diperlukan 10.000 baris tambahan untuk tes unit. Untuk program pemrosesan paket saya, ini berarti satu-satunya komponen eksternal yang saya gunakan adalah:
Beberapa hal yang saya implementasikan sendiri karena sederhana termasuk bahkan hal-hal seperti:
... karena implementasi khusus ini dapat memungkinkan inlining berat, yang mengarah ke peningkatan kinerja.
Saya tidak melakukan kriptografi; jika saya melakukannya, saya akan menambahkan beberapa jenis perpustakaan kripto dalam daftar, karena menulis algoritma kripto Anda sendiri mungkin rentan terhadap serangan waktu cache bahkan jika Anda dapat dengan pengujian unit menyeluruh menunjukkan bahwa mereka kompatibel dengan algoritma resmi.
sumber
Pustaka inti dapat menjadi buruk ketika banyak proyek bergantung padanya, Anda tidak hanya harus menguji perubahan apa pun pada inti Anda, tetapi Anda juga harus menguji kemunduran setiap proyek bergantung. Kedua, API inti Anda tidak akan pernah bisa berubah karena Anda harus memperbaiki setiap proyek yang bergantung. Semakin banyak proyek yang menggunakan perpustakaan Anda, semakin dalam jebakan.
Masalah lain adalah kecenderungan untuk mulai melemparkan segala sesuatu yang "biasa" ke perpustakaan inti Anda, membengkaknya dan membuatnya lebih sulit untuk menarik bagian-bagian kecil. Saya hanya akan mengatakan bahwa pada suatu waktu saya mendengar tentang suatu tempat yang menjadi takut untuk menyentuh salah satu dari banyak perpustakaan inti mereka, overhead pengujian regresi QA begitu besar.
Alih-alih, mungkin Anda dapat membuat sumber snipet kode untuk membiarkan tim proyek mencari dan menarik kode yang mereka butuhkan dan memisahkan diri dari masalah pemeliharaan atau regresi? Itu yang saya lakukan di rumah.
sumber
Satu hal yang belum disebutkan adalah bahwa setiap kode akan memiliki ketergantungan pada sesuatu , bahkan jika itu benar-benar berjalan di ROM mikrokontroler yang tertanam; jika pembuat pengontrol mengubah beberapa perilaku yang diandalkan oleh kode, kode tersebut harus dimodifikasi untuk bekerja pada chip yang diproduksi setelah perubahan, atau produsen perangkat yang menggunakan kode harus entah bagaimana memperoleh chip yang melakukan tidak memasukkan perubahan - mungkin membayar harga premium untuk mereka.
Menggunakan pustaka untuk melakukan berbagai fungsi perangkat keras dapat berarti bahwa kode sekarang tergantung pada pustaka yang sebelumnya tidak, tetapi juga dapat menghilangkan ketergantungan antara kode dan perangkat keras. Sebagai contoh, produsen chip mungkin berjanji untuk memasok perpustakaan untuk semua chip sekarang dan masa depan yang akan selalu melakukan fungsi I / O tertentu dengan cara tertentu. Kode yang menggunakan pustaka itu untuk melakukan fungsi-fungsi I / O tersebut akan menjadi bergantung pada pabrikan untuk menyediakan versi pustaka yang sesuai, tetapi tidak lagi tergantung pada pabrikan untuk menggunakan implementasi perangkat keras yang sama dari fungsi-fungsi tersebut.
Sayangnya, seringkali sulit untuk mengetahui pendekatan mana yang tepat untuk kode pemeriksaan masa depan. Saya telah melihat kasus di mana vendor chip mengubah cara perpustakaan bekerja (sehingga dapat mengakomodasi chip baru), bahkan ketika sedang digunakan untuk mengakses chip yang telah berubah. Saya juga melihat kasus di mana produsen chip mengubah cara perangkat kerasnya bekerja, tetapi perpustakaan yang disediakan disesuaikan dengan tepat, sehingga kode yang menggunakan rutinitas perpustakaan akan terus bekerja tanpa perubahan, sementara kode yang mengakses perangkat keras secara langsung harus disesuaikan.
Situasi serupa ada dengan aplikasi Windows. Microsoft terkadang suka mengubah cara aplikasi diperlukan untuk melakukan sesuatu; kode yang menggunakan perpustakaan tertentu untuk hal-hal seperti itu dapat ditingkatkan hanya dengan memperbarui perpustakaan, sedangkan kode yang tidak menggunakan perpustakaan yang diperbarui untuk mereka harus diperbarui secara manual.
sumber
Saya ingin ikut serta dengan pandangan yang sedikit berbeda, meskipun saya suka
Denis de Bernardy
jawaban dan artikel terkait tentang meminimalkan dependensi vs meminimalkan redudansi (mereka sangat mencerminkan pemikiran saya sendiri tentang masalah ini di mana saya percaya penggunaan kembali kode adalah tindakan penyeimbang).Masalah terbesar yang saya miliki dengan
core
perpustakaan adalah ini:Dan saya pikir sangat mungkin jawabannya " tidak pernah ". Orang-orang mungkin selalu tergoda untuk menambahkannya karena memodelkan ide yang samar-samar, terutama jika perpustakaan ini baru saja berkembang selama pengembangan perangkat lunak alih-alih memiliki tujuan yang telah diantisipasi dengan baik di muka. Dan mungkin menambahkan ke perpustakaan bukan hal terburuk di dunia karena tidak akan memutus ketergantungan yang ada ke perpustakaan, tetapi mengingat tujuan samar-samar seperti itu, perpustakaan bisa tumbuh semakin eklektik dan jelek, menyediakan fungsi berbeda yang diminati seseorang yang tertarik pada perpustakaan. menggunakan perpustakaan mungkin hanya menemukan sebagian kecil dari itu berlaku untuk kebutuhan mereka.
Ketergantungan pada basis kode Anda idealnya mengalir ke paket yang sangat stabil. Suatu
core
paket dapat dengan mudah menemukan dirinya sangat tidak stabil sementara sebagian besar basis kode Anda memiliki ketergantungan mengalir ke sana.Jadi saya pikir ada baiknya membagi perpustakaan menjadi perpustakaan yang lebih seragam yang ditujukan untuk melakukan sesuatu yang lebih spesifik dari sekadar, "perpustakaan inti dari hal apa pun yang sering dibutuhkan orang" sehingga perpustakaan dapat tumbuh ke arah yang lebih seragam dengan koordinasi yang lebih baik di antara rekan tim Anda tentang apa yang seharusnya dan, yang lebih penting, tidak boleh dilakukan, dan berpotensi mencapai titik stabilitas di mana ia telah teruji dengan baik dan Anda tidak merasa ada hal lain yang perlu ditambahkan padanya agar menjadi relatif " lengkap "dan stabil (seperti dalam, tidak berubah).
sumber
Menulis perpustakaan untuk hal-hal dasar seperti string dan daftar tertaut cukup konyol di milenium ini. Gunakan bahasa pemrograman termasuk baterai yang memiliki fungsi inti sudah ada di dalamnya.
Jika Anda suka menulis perpustakaan dukungan run-time inti hanya untuk bersenang-senang, maka rancang bahasa pemrograman baru. Jika Anda melakukannya dalam suatu aplikasi, maka pada dasarnya Anda mengembangkan bahasa dari sisinya.
Selain itu, bukankah seseorang sudah menulis N perpustakaan inti yang berbeda dalam bahasa yang Anda gunakan? Meneliti kerangka kerja yang ada dan memilih yang paling cocok mungkin lebih baik menggunakan waktu daripada melakukannya dari awal.
sumber