Bagi saya, kode boilerplate jelas buruk. Namun saya telah bertemu dengan seorang pengembang yang menampilkan resistansi dalam setiap upaya untuk mengurangi boilerplate. Saya menyadari bahwa saya tidak memiliki argumen yang siap dibentuk, dipikirkan dengan baik melewati kebencian yang telah saya kembangkan selama ini.
Agar saya dapat membentuk argumen yang meyakinkan untuk mendukung pelat yang lebih sedikit, apa sajakah yang bertentangan? Dengan kata lain, apa argumen (jika ada) yang mendukung boilerplate?
(Maksud saya apa yang saya pikir pada umumnya dimaksudkan dengan boilerplate, tetapi contoh yang baik adalah getter dan setters di Jawa.)
Jawaban:
Satu hal penting untuk diingat adalah bahwa kode umumnya dibuat lebih kecil dengan menghapus konteks yang tidak perlu. Jika kompilator dapat menemukan sesuatu, argumen itu berbunyi, tidak perlu menuliskannya secara eksplisit.
Dan itu akan bagus jika hanya kompiler yang pernah bermaksud membacanya. Tetapi ingat bahwa "program harus ditulis untuk dibaca orang, dan hanya secara kebetulan untuk dijalankan oleh mesin." (Ironisnya, kutipan ini berasal dari buku teks yang didedikasikan untuk salah satu yang paling sulit dari semua bahasa untuk dibaca oleh manusia biasa, sebagian besar karena kesegarannya yang berlebihan.)
Apa yang terlihat seperti membosankan, berulang-ulang bagi Anda ketika Anda menulisnya dapat menjadi konteks yang berharga bagi orang lain yang datang setahun (atau lima) kemudian dan harus menjaga kode Anda.
WRT contoh Java secara khusus, saya akan setuju bahwa itu adalah contoh yang baik dari platplate yang buruk, karena dapat diganti dengan sesuatu yang lebih pendek dan lebih mudah dibaca, dan juga lebih fleksibel: Properti. Tetapi itu tidak berarti bahwa semua elemen sintaksis boilerplate dari semua bahasa sama borosnya dengan getter dan setter dari Java dan C ++.
sumber
Salah satu argumen yang mendukung kode boilerplate adalah bahwa jika Anda mengubahnya di satu tempat, itu hanya mempengaruhi satu aliran kode. Ini harus diseimbangkan dengan fakta bahwa lebih-sering-daripada-tidak, Anda benar-benar ingin perubahan mempengaruhi setiap bagian dari kode yang menggunakannya. Tetapi saya telah melihat contoh langka yang mendukung argumen.
Katakanlah Anda memiliki kode yang bertuliskan
Ini digunakan di sekitar 2 tempat dalam kode Anda.
Suatu hari seseorang datang dan berkata "ok, di jalur ini saja, kami ingin Anda Grommit bar sebelum Fooing itu."
Dan Anda berpikir "yah ini sederhana."
Kemudian pengguna Anda menambahkan beberapa fungsi baru dan Anda merasa cocok dengan FooTheBar. Dan Anda patuh bertanya kepada mereka apakah Anda harus Grommit bar itu sebelum Anda Foo dan mereka berkata "tidak, tidak kali ini".
Jadi Anda tinggal memanggil metode di atas.
Tetapi kemudian pengguna Anda berkata "ok, tunggu, dalam kasus ketiga, kami ingin Anda mencoret-coret Bar sebelum menelepon BeFooed."
Tidak masalah, Anda pikir, saya bisa melakukannya.
Tiba-tiba kode Anda menjadi kurang matang. Mungkin Anda seharusnya menerima dua baris kode yang berulang. Sekarang Anda akan memiliki tiga potong kode, masing-masing panjangnya 2-3 baris dan tidak terlihat berulang lagi.
Semua ini berkata, saya akan membantah bahwa dengan "ini bukan kasus yang umum, dan ketika itu terjadi, Anda dapat refactor."
Argumen lain yang baru-baru ini saya dengar adalah bahwa kode boilerplate terkadang dapat membantu Anda menavigasi kode. Contoh yang kami diskusikan adalah di mana kami telah menghapus banyak kode pemetaan boilerplate dan menggantinya dengan AutoMapper. Sekarang, itu diperdebatkan, karena semuanya berbasis konvensi, Anda tidak bisa mengatakan "Di mana properti ini diatur," ke IDE dan berharap untuk mengetahuinya.
Saya telah melihat orang-orang memperdebatkan hal-hal serupa tentang wadah IoC.
Bukan untuk mengatakan bahwa saya setuju dengan mereka, tetapi itu adalah argumen yang adil.
sumber
Evolusi efisiensi
Anda mulai dengan ini:
maka Anda menyingkirkan semua boilerplate yang mengganggu dan memasukkannya ke dalam fungsi:
createFieldHtml( id, label )
ini bagus, saya menyimpan sendiri begitu banyak baris!
createFieldHtml( id, label, defaultValue )
ya, saya butuh nilai default juga, itu mudah ditambahkan.
createFieldHtml( id, label, defaultValue, type )
keren, saya bisa menggunakannya untuk kotak centang sekarang juga
createFieldHtml( id, label, defaultValue, type, labelFirst )
Perancang UX mengatakan label harus setelah kotak centang.
createFieldHtml( id, label, defaultValue, type, labelFirst, isDate )
sekarang membuat pemilih tanggal saat dibutuhkan. Hm .. params semakin tidak terkendali
createFieldHtml( id, label, defaultValue, type, labelFirst, isDate, containerCssClasses )
ada satu kasus ini di mana saya perlu menambahkan kelas CSS
createFieldHtml( id, label, defaultValue, type, labelFirst, isDate, containerCssClasses, fieldCssClasses, disabled, clearAfter, helpText, uploadPath )
aaaaaaaaaaaaaaaaaaaaa
Mempertahankan boilerplate
Saya mengalami kesulitan memasukkan kata-kata ini karena ini benar-benar sesuatu yang saya perhatikan baru-baru ini, jadi saya akan membuat daftar:
Satu hal yang saya selalu tanyakan pada diri sendiri adalah ini:
Dapatkah saya menyalin & menempel ke proyek lain tanpa mengubah apa pun? jika ya, tidak apa-apa untuk merangkum atau dimasukkan ke dalam perpustakaan, jika tidak: saatnya boilerplate.
Ini sangat bertentangan dengan persepsi umum bahwa boilerplate adalah kode copy & paste. Bagi saya boilerplate adalah tentang copy & paste, tetapi selalu harus sedikit men-tweak.
Pembaruan : Saya baru saja menemukan artikel yang memberikan contoh saya di atas nama sebenarnya: "terlalu anti-pola KERING".
Ini bacaan singkat dan menarik, Anda dapat menemukan artikel di sini: Anti-Pola Terlalu Kering
sumber
Saya membenci kode boilerplate, tetapi bisa menghapus kode boilerplate tidak selalu berarti itu adalah cara terbaik untuk pergi.
Kerangka WPF memiliki sifat ketergantungan , yang melibatkan jumlah kode boilerplate yang gila. Selama waktu luang saya, saya menyelidiki solusi yang sangat mengurangi jumlah kode yang perlu ditulis. Lebih dari satu tahun kemudian saya masih meningkatkan solusi ini , dan masih perlu memperluas fungsionalitasnya atau memperbaiki bug.
Apa masalahnya? Ini bagus untuk mempelajari hal baru, dan mencari solusi alternatif, tetapi itu mungkin bukan keputusan komersial terbaik .
Kerangka kerja WPF didokumentasikan dengan baik. Itu benar mendokumentasikan bagaimana menulis kode boilerplate Anda. Mencoba untuk menghapus kode boilerplate ini adalah latihan yang bagus, dan sesuatu yang pasti perlu ditelusuri, tetapi mencapai tingkat 'polesan' yang sama seperti yang ditawarkan msdn membutuhkan waktu lama, yang tidak selalu kita miliki.
sumber
Masalah dengan boilerplate adalah melanggar KERING. Intinya, ketika Anda menulis boilerplate, Anda mengulangi kode yang sama (atau kode yang sangat mirip) di sejumlah kelas. Ketika kode itu perlu diubah, sama sekali tidak pasti bahwa pengembang akan mengingat semua tempat kode itu diulang. Ini mengarah ke bug di mana API lama atau metode lama digunakan.
Jika Anda membuat ulang boilerplate ke perpustakaan umum atau kelas induk, maka Anda hanya perlu mengubah kode di satu tempat ketika API Anda berubah. Lebih penting lagi, ketika perubahan tak terduga terjadi, kode terputus di satu tempat, dan membuat Anda tahu persis apa yang harus Anda perbaiki agar semuanya kembali berfungsi. Ini jauh lebih disukai daripada skenario di mana satu perubahan menyebabkan kegagalan dalam lusinan, atau bahkan ratusan kelas.
sumber
Saya akan mengambil kebijaksanaan yang berbeda. Konsistensi dalam pengembangan adalah salah satu fitur terpenting dari desain perangkat lunak, ini adalah alat penting dalam membuat aplikasi dapat diperluas dan dipelihara tetapi bisa sulit dicapai ketika mengelola tim di berbagai situs, bahasa, dan zona waktu.
Jika tercapai, konsistensi membuat kode jauh lebih mudah diakses "begitu Anda melihatnya, Anda telah melihat semuanya", jauh lebih murah untuk dirawat dan diperbaiki, tetapi di atas semua itu, jauh lebih mudah untuk diperluas. Saat Anda menulis pustaka yang memang membutuhkan beberapa pelat, bersamaan dengan kekuatan pustaka Anda, Anda juga telah memberi pengembang:
Ketika konsumen perpustakaan Anda menguasai instantiasi, mereka dapat dengan mudah membuat metode pribadi / ekstensi, kelas induk atau bahkan templat untuk mengimplementasikan kode boilerplate.
sumber
Satu-satunya masalah nyata dengan kode boilerplate adalah bahwa ketika Anda menemukan bug di dalamnya Anda harus memperbaiki di mana-mana Anda menggunakannya daripada satu-satunya tempat yang Anda gunakan kembali .
sumber