Ketika berhadapan dengan algoritma rumit dalam bahasa dengan dukungan untuk fungsi bersarang (seperti Python dan D) saya sering menulis fungsi besar (karena algoritme rumit) tetapi mengurangi ini dengan menggunakan fungsi bersarang untuk menyusun kode rumit. Apakah fungsi besar (100+ garis) masih dianggap jahat meskipun terstruktur dengan baik secara internal melalui penggunaan fungsi bersarang?
Sunting: Bagi Anda yang tidak terbiasa dengan Python atau D, fungsi bersarang dalam bahasa ini juga memungkinkan akses ke lingkup fungsi luar. Di D, akses ini memungkinkan mutasi variabel di lingkup luar. Dalam Python hanya memungkinkan membaca. Dalam D Anda dapat secara eksplisit menonaktifkan akses ke lingkup luar di fungsi bersarang dengan mendeklarasikannya static
.
Jawaban:
Selalu ingat aturannya, sebuah fungsi melakukan satu hal dan melakukannya dengan baik! Jika Anda bisa melakukannya, hindari fungsi bersarang.
Ini menghambat keterbacaan dan pengujian.
sumber
Beberapa berpendapat bahwa fungsi pendek bisa lebih rentan kesalahan daripada fungsi panjang .
Secara pribadi, saya telah menemukan bahwa kode garis lurus yang dikomentari dengan baik lebih mudah untuk diikuti (terutama ketika Anda bukan orang yang awalnya menulisnya) daripada ketika itu dipecah menjadi beberapa fungsi yang tidak pernah digunakan di tempat lain. Tetapi itu benar-benar tergantung pada situasinya.
Saya pikir kesimpulan utama adalah ketika Anda membagi satu blok kode, Anda memperdagangkan satu jenis kompleksitas untuk yang lain. Mungkin ada titik manis di suatu tempat di tengah.
sumber
Idealnya, seluruh fungsi harus dapat dilihat tanpa harus menggulir. Terkadang, ini tidak mungkin. Tetapi jika Anda dapat memecahnya menjadi beberapa bagian maka itu akan membuat membaca kode jauh lebih mudah.
Saya tahu bahwa segera setelah saya mendorong Page Up / Down atau pindah ke bagian kode yang berbeda, saya hanya dapat mengingat 7 +/- 2 hal dari halaman sebelumnya. Dan sayangnya, beberapa lokasi tersebut akan digunakan ketika membaca kode baru.
Saya selalu suka memikirkan memori jangka pendek saya seperti register komputer (CISC, bukan RISC). Jika Anda memiliki seluruh fungsi pada halaman yang sama, Anda dapat pergi ke cache untuk mendapatkan informasi yang diperlukan dari bagian lain dari program. Jika seluruh fungsi tidak dapat ditampung pada halaman, itu akan menjadi setara dengan selalu mendorong memori ke disk setelah setiap operasi.
sumber
Mengapa menggunakan fungsi bersarang, daripada fungsi eksternal normal?
Sekalipun fungsi eksternal hanya pernah digunakan dalam fungsi Anda, yang sebelumnya-besar, masih membuat keseluruhan kekacauan lebih mudah dibaca:
sumber
Saya tidak memiliki buku di depan saya saat ini (untuk mengutip), tetapi menurut Kode Lengkap "sweetspot" untuk panjang fungsi sekitar 25-50 baris kode menurut penelitiannya.
Ada saatnya ok memiliki fungsi yang panjang:
Saat tidak memiliki fungsi panjang:
Intinya adalah bahwa pemeliharaan harus menjadi salah satu prioritas tertinggi dalam daftar Anda. Jika pengembang lain tidak dapat melihat kode Anda dan mendapatkan "inti" dari apa yang dilakukan kode dalam waktu kurang dari 5 detik, kode Anda tidak memberikan cukup "metadata" untuk mengetahui apa yang dilakukannya. Pengembang lain harus dapat mengetahui apa yang dikerjakan oleh kelas Anda hanya dengan melihat browser objek di IDE yang Anda pilih alih-alih membaca 100 baris kode.
Fungsi yang lebih kecil memiliki keunggulan sebagai berikut:
Daftar ini berlanjut .....
sumber
Jawabannya tergantung, namun Anda mungkin harus mengubahnya menjadi kelas.
sumber
Saya tidak suka sebagian besar fungsi bersarang. Lambdas termasuk dalam kategori itu tetapi biasanya tidak menandai saya kecuali mereka memiliki lebih dari 30-40 karakter.
Alasan dasarnya adalah bahwa itu menjadi fungsi yang sangat lokal dengan rekursi semantik internal, yang berarti bahwa sulit bagi saya untuk membungkus otak saya, dan hanya lebih mudah untuk mendorong beberapa hal keluar ke fungsi pembantu yang tidak mengacaukan ruang kode .
Saya menganggap bahwa fungsi harus Melakukan Hal Ini. Melakukan Hal Lain adalah fungsi yang dilakukan fungsi lain. Jadi jika Anda memiliki fungsi 200-line Melakukan Hal, dan semuanya mengalir, itu A-OK.
sumber
Apakah ini dapat diterima? Itu benar-benar pertanyaan yang hanya bisa Anda jawab. Apakah fungsi tersebut mencapai apa yang diperlukan? Apakah bisa dirawat? Apakah 'dapat diterima' oleh anggota tim Anda yang lain? Jika demikian, maka itulah yang benar-benar penting.
Sunting: Saya tidak melihat hal tentang fungsi bersarang. Secara pribadi, saya tidak akan menggunakannya. Saya akan menggunakan fungsi reguler sebagai gantinya.
sumber
Fungsi "garis-lurus" yang panjang bisa menjadi cara yang jelas untuk menentukan urutan panjang langkah-langkah yang selalu terjadi dalam urutan tertentu.
Namun, seperti yang telah disebutkan orang lain, formulir ini cenderung memiliki kompleksitas lokal di mana aliran keseluruhan kurang jelas. Menempatkan kompleksitas lokal itu ke fungsi bersarang (yaitu: didefinisikan di tempat lain dalam fungsi panjang, mungkin di atas atau bawah) dapat mengembalikan kejelasan ke aliran arus utama.
Pertimbangan penting kedua adalah mengendalikan ruang lingkup variabel yang dimaksudkan untuk digunakan hanya dalam rentang lokal dari fungsi yang panjang. Diperlukan kewaspadaan untuk menghindari variabel yang diperkenalkan dalam satu bagian kode tanpa disadari dirujuk di tempat lain (misalnya, setelah siklus pengeditan), karena kesalahan semacam ini tidak akan muncul sebagai kesalahan kompilasi atau runtime.
Dalam beberapa bahasa, masalah ini mudah dihindari: rangkaian kode lokal dapat dibungkus dengan bloknya sendiri, seperti dengan "{...}", di mana variabel yang baru diperkenalkan hanya dapat dilihat oleh blok itu. Beberapa bahasa, seperti Python, kekurangan fitur ini, dalam hal ini fungsi lokal dapat berguna untuk menegakkan wilayah lingkup yang lebih kecil.
sumber
Tidak, fungsi multi-halaman tidak diinginkan, dan tidak boleh melewati tinjauan kode. Saya dulu menulis fungsi panjang juga, tetapi setelah membaca Refactoring Martin Fowler , saya berhenti. Fungsi panjang sulit untuk ditulis dengan benar, sulit dimengerti dan sulit untuk diuji. Saya belum pernah melihat fungsi bahkan 50 baris yang tidak akan lebih mudah dipahami dan diuji jika dipecah menjadi satu set fungsi yang lebih kecil. Dalam fungsi multi-halaman hampir pasti seluruh kelas yang harus diperhitungkan. Sulit untuk lebih spesifik. Mungkin Anda harus memposting salah satu fungsi panjang Anda ke Code Review dan seseorang (mungkin saya) dapat menunjukkan kepada Anda bagaimana memperbaikinya.
sumber
Ketika saya sedang memprogram dalam python, saya ingin mundur setelah saya menulis sebuah fungsi dan bertanya pada diri sendiri apakah itu mematuhi "Zen of Python" (ketik 'import this' dalam interpreter python Anda):
Cantik lebih baik daripada jelek.
Eksplisit lebih baik daripada implisit.
Sederhana lebih baik daripada kompleks.
Kompleks lebih baik daripada rumit.
Flat lebih baik daripada bersarang.
Jarang lebih baik daripada padat.
Jumlah keterbacaan diperhitungkan.
Kasus khusus tidak cukup istimewa untuk melanggar aturan.
Meskipun kepraktisan mengalahkan kemurnian.
Kesalahan tidak boleh terjadi secara diam-diam.
Kecuali secara eksplisit dibungkam.
Dalam menghadapi ambiguitas, tolak godaan untuk menebak.
Harus ada satu - dan lebih disukai hanya satu - cara yang jelas untuk melakukannya.
Meskipun demikian mungkin tidak jelas pada awalnya kecuali Anda orang Belanda.
Sekarang lebih baik daripada tidak sama sekali.
Meskipun tidak pernah sering lebih baik daripada benarsekarang.
Jika implementasi sulit dijelaskan, itu ide yang buruk.
Jika implementasinya mudah dijelaskan, mungkin itu ide yang bagus.
Namespaces adalah salah satu ide bagus - mari kita lakukan lebih dari itu!
sumber
Tempatkan mereka di modul terpisah.
Dengan asumsi solusi Anda tidak lebih besar daripada membutuhkan Anda tidak punya terlalu banyak pilihan. Anda telah membagi fungsi dalam berbagai sub fungsi sehingga pertanyaannya adalah di mana Anda harus meletakkannya:
Sekarang baik alternatif kedua dan ketiga dalam beberapa hal bersarang, tetapi alternatif kedua oleh beberapa programmer tampaknya tidak buruk. Jika Anda tidak mengesampingkan alternatif kedua, saya tidak melihat terlalu banyak alasan untuk mengesampingkan alternatif ketiga.
sumber