Apakah panjang fungsi memengaruhi produktivitas programmer? Jika demikian, berapakah jumlah maksimum garis yang baik untuk menghindari hilangnya produktivitas?
Karena ini adalah topik yang sangat banyak pendapat, harap buat cadangan klaim dengan beberapa data.
programming-practices
coding-standards
Peter Mortensen
sumber
sumber
Jawaban:
Sejak saya memulai raket gila ini pada tahun 1970, saya telah melihat persis satu modul yang benar-benar perlu lebih dari satu halaman yang dicetak (sekitar 60 baris). Saya telah melihat banyak modul yang lebih panjang.
Dalam hal ini, saya memiliki modul tertulis yang lebih panjang, tetapi mereka biasanya mesin negara hingga terbatas ditulis sebagai pernyataan switch besar.
Bagian dari masalah tampaknya adalah bahwa programmer hari ini tidak diajarkan untuk memodulasi hal-hal.
Standar pengkodean yang memaksimalkan pemborosan ruang vertikal tampaknya juga menjadi bagian dari masalah. (Saya belum bertemu dengan seorang manajer perangkat lunak yang telah membaca " Psikologi Pemrograman Komputer " dari Gerald Weinberg . Weinberg menunjukkan bahwa banyak penelitian telah menunjukkan bahwa pemahaman programmer pada dasarnya terbatas pada apa yang dapat dilihat oleh programmer pada saat tertentu. Jika programmer harus menggulir, atau membalik halaman, pemahaman mereka turun secara signifikan: mereka harus ingat, dan abstrak.)
Saya tetap yakin bahwa banyak keuntungan produktivitas programmer yang didokumentasikan dengan baik dari FORTH adalah karena sistem "blok" FORTH untuk kode sumber: modul-modul sangat terbatas hingga maksimum 16 baris 64 karakter. Anda dapat faktor tak terhingga, tetapi Anda tidak bisa dalam keadaan apa pun menulis rutin 17-baris.
sumber
Apa Ukuran yang Tepat, Benarkah?
Tergantung pada bahasa yang Anda gunakan, tetapi secara umum (dan untuk selera pribadi saya):
Jika lebih, maka itu adalah sesuatu yang saya harus kembali lagi nanti dan mengerjakan ulang.
Tetapi secara realistis , ukuran apa pun yang diperlukan adalah ketika Anda perlu mengirimkan sesuatu dan bahwa lebih masuk akal saat ini untuk memuntahkannya, membuat kadang-kadang lebih mudah bagi seseorang untuk meninjau sebelum pengiriman. (tapi masih bisa kembali lagi nanti).
(Baru-baru ini tim saya menjalankan program pada basis kode kami: kami menemukan kelas dengan 197 metode dan yang lain hanya dengan 3 metode tetapi salah satunya adalah 600 baris. Permainan lucu: apa yang lebih buruk dari 2 kejahatan?)
Sekarang untuk jawaban yang lebih zen ... Secara umum itu dianggap praktik yang baik (TM) mengutip satu atau dua orang hebat, jadi begini:
Tambahan pada Gaya Komentar
Sebagai tambahan untuk ini, fungsi Anda harus memiliki nama yang jelas menjelaskan maksudnya. Mengenai komentar, saya biasanya tidak berkomentar di dalam suatu fungsi:
Blok komentar di bagian atas setiap fungsi (yang membutuhkan penjelasan) sudah cukup. Jika fungsi Anda kecil dan nama fungsi cukup eksplisit, maka Anda hanya perlu mengatakan apa yang ingin Anda capai dan mengapa. Saya menggunakan komentar sebaris hanya untuk bidang dalam beberapa bahasa atau pada blok dimulai untuk fungsi yang melanggar aturan garis 25-35 jika maksudnya tidak jelas. Saya menggunakan komentar blok di dalam kode ketika situasi luar biasa terjadi (blok tangkapan di mana Anda tidak perlu atau ingin melakukan apa pun harus memiliki komentar yang mengatakan mengapa, misalnya).
Untuk lebih lanjut, silakan baca jawaban saya tentang Gaya dan rekomendasi kode komentar
sumber
tt
untuk menghasilkan ini tetapi kadang-kadang Anda terjebak dengan fungsi pantat panjang (atau fungsi pantat panjang) yang tidak benar-benar melakukan sesuatu yang menarik pula jadi bukan masalah nyata.Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);
agak jelas bahwa semuanya sama saja. (Perhatikan ini hanyalah sebuah contoh; fungsi semacam ini memang muncul dari waktu ke waktu)Menurut pendapat saya, setiap fungsi harus sekecil mungkin. Setiap fungsi seharusnya hanya melakukan satu hal dan melakukannya dengan baik. Itu tidak benar-benar menjawab pertanyaan panjang maksimum, tetapi lebih pada perasaan saya pada panjang fungsi.
Untuk menggunakan kata-kata Paman Bob, "Ekstrak sampai Anda tidak bisa mengekstraksi lagi. Ekstrak sampai Anda jatuh."
sumber
Berapakah ketinggian maksimum sebuah bangunan? Tergantung di mana bangunan itu berada, atau ketinggian yang Anda inginkan.
Anda mungkin mendapat jawaban berbeda dari orang yang berbeda yang berasal dari kota yang berbeda.
Beberapa fungsi skrip dan penangan interupsi kernel sangat panjang.
sumber
Metode yang bekerja untuk saya adalah: Dapatkah saya memiliki bagian dari fungsi yang lebih panjang memberikan nama yang masuk akal. Saya pikir panjang metode tidak begitu penting seperti penamaan yang baik. Metode harus melakukan apa yang dikatakan namanya, tidak lebih dan tidak kurang. Dan Anda harus bisa memberikan nama yang bagus. Jika Anda tidak dapat menyebutkan metode Anda dengan baik, kodenya mungkin tidak bagus jika digabungkan.
sumber
Selama itu perlu untuk melakukan apa yang perlu dilakukan, tetapi tidak lagi.
sumber
Saya pikir ada trade off. Jika Anda memiliki banyak metode pendek, seringkali lebih sulit untuk men-debug mereka daripada satu metode panjang. Jika Anda harus melompati editor 20 atau 30 waktu yang berbeda untuk melacak satu panggilan metode, akan sulit untuk menyimpan semuanya di kepala Anda. Sementara itu jika ada satu metode jelas yang ditulis dengan baik, bahkan jika itu adalah 100 baris, sering kali lebih mudah diingat.
Pertanyaan sebenarnya adalah mengapa item harus dalam metode yang berbeda, dan jawaban seperti yang diberikan di atas adalah penggunaan kembali kode. Jika Anda tidak menggunakan kembali kode (atau tidak tahu) maka mungkin masuk akal untuk meninggalkannya dalam satu metode raksasa yang mudah diikuti dan kemudian karena Anda perlu menggunakannya kembali, bagi bagian-bagian yang perlu diulang kembali. menggunakan metode yang lebih kecil.
Pada kenyataannya bagian dari desain metode yang baik adalah membuat metode kohesif fungsional (pada dasarnya mereka melakukan satu hal). Panjang metode tidak masalah. Jika suatu fungsi melakukan satu hal yang didefinisikan dengan baik dan 1.000 baris daripada itu adalah metode yang baik. Jika suatu fungsi melakukan 3 atau 4 hal dan hanya 15 baris, maka itu adalah metode yang buruk ...
sumber
Saya merasa lebih mudah untuk melacak apa yang saya lakukan jika saya dapat melihat seluruh fungsi sekaligus. Jadi, inilah cara saya lebih suka menulis fungsi:
Saya jarang menulis fungsi lebih lama dari itu. Kebanyakan dari mereka adalah pernyataan switch C / C ++ raksasa.
sumber
Bagi saya, sebuah fungsi adalah berapa pun panjangnya. Sebagian besar waktu saya membaginya adalah ketika saya akan menggunakan kembali kode.
Pada dasarnya, saya akan tetap berpegang pada prinsip 'kohesi tinggi, kopling rendah' dan tidak ada batasan panjang.
sumber
Pertanyaannya seharusnya adalah berapa banyak hal yang harus dilakukan suatu fungsi. Dan biasanya, jarang sekali Anda membutuhkan 100 baris untuk melakukan "satu" hal. Sekali lagi itu tergantung pada tingkat dari mana Anda melihat kode: Apakah hashing kata sandi satu hal? Atau apakah hashing dan menyimpan kata sandi adalah satu hal?
Saya akan mengatakan, mulailah dengan menyimpan kata sandi sebagai satu fungsi. Ketika Anda merasa bahwa hashing berbeda, dan Anda memperbaiki kode. Saya bukan programmer ahli dengan cara apa pun, tetapi IMHO, seluruh ide fungsi mulai kecil adalah bahwa semakin atom fungsi Anda, semakin tinggi peluang kode digunakan kembali, tidak pernah harus membuat perubahan yang sama di lebih dari satu tempat , dll.
Saya telah melihat prosedur tersimpan SQL yang menjalankan lebih dari 1000 baris. Apakah jumlah garis prosedur tersimpan juga kurang dari 50? Saya tidak tahu, tetapi itu membuat membaca kode, neraka. Anda tidak hanya harus terus menggulir ke atas dan ke bawah, Anda perlu memberikan beberapa baris kode nama seperti "this does validation1", "ini pembaruan dalam database", dll. - sebuah pekerjaan yang seharusnya dilakukan oleh programmer.
sumber
Dari Kompleksitas Cyclomatic (Wikipedia):
Saya sarankan Anda menyimpan nomor itu di bawah 10 dalam satu metode. Jika mencapai 10, maka sudah waktunya faktor ulang.
Ada alat yang dapat mengevaluasi kode Anda dan memberi Anda nomor kompleksitas siklomatik.
Anda harus berusaha mengintegrasikan alat-alat ini ke dalam pipeline build Anda.
Jangan benar-benar mengejar ukuran metode, tetapi cobalah untuk melihat kompleksitas dan tanggung jawabnya. Jika memiliki lebih dari satu tanggung jawab, maka mungkin ide yang baik untuk mempertimbangkan ulang faktor. Jika kompleksitas siklomatiknya meningkat, maka mungkin inilah saatnya untuk mempertimbangkan ulang.
Saya cukup yakin ada alat lain yang memberi Anda umpan balik yang serupa, tetapi saya belum memiliki kesempatan untuk melihat ini.
sumber
Biasanya, saya mencoba menjaga metode / fungsi saya agar sesuai dengan layar monitor 1680x1050. Jika tidak cocok, maka gunakan metode / fungsi pembantu untuk membagi tugas.
Ini membantu keterbacaan pada layar dan kertas.
sumber
Saya tidak menetapkan batas garis keras pada apa pun karena beberapa fungsi mengimplementasikan algoritma yang secara inheren kompleks dan upaya apa pun untuk membuatnya lebih pendek akan membuat interaksi antara yang baru, fungsi yang lebih pendek begitu rumit sehingga hasil bersihnya tidak akan berkurang dalam kesederhanaan. Saya juga tidak percaya bahwa gagasan bahwa suatu fungsi seharusnya hanya melakukan "satu hal" adalah panduan yang baik, karena "satu hal" pada abstraksi tingkat tinggi dapat menjadi "banyak hal" pada tingkat yang lebih rendah.
Bagi saya, suatu fungsi pasti terlalu panjang jika panjangnya menyebabkan pelanggaran DRY yang halus sekarang, dan mengekstraksi bagian dari fungsi ke dalam fungsi atau kelas baru bisa menyelesaikannya. Suatu fungsi mungkin terlalu lama jika ini tidak terjadi, tetapi suatu fungsi atau kelas dapat dengan mudah diekstraksi yang akan membuat kode lebih modular dengan cara yang mungkin berguna dalam menghadapi perubahan yang akan terjadi di masa mendatang.
sumber
Cukup pendek untuk dioptimalkan dengan benar
Metode harus sangat singkat untuk melakukan tepat satu hal. Alasannya sederhana: agar kode Anda dapat dioptimalkan dengan benar.
Dalam bahasa ted-JIT seperti Java atau C #, penting agar metode Anda sederhana sehingga kompiler JIT dapat menghasilkan kode dengan cepat. Metode yang lebih lama, lebih rumit tentu membutuhkan lebih banyak waktu JIT. Juga, kompiler JIT hanya menawarkan beberapa optimisasi dan hanya metode yang paling sederhana yang diuntungkan dari ini. Fakta ini bahkan disebut dalam Bill Wagner's Effective C # .
Dalam bahasa tingkat rendah, seperti C atau C ++, memiliki metode pendek (mungkin selusin baris) juga penting karena dengan cara itu Anda meminimalkan kebutuhan untuk menyimpan variabel lokal dalam RAM daripada dalam register. (Aka 'Register Spilling'.) Namun, perlu diketahui bahwa dalam kasus yang tidak dikelola ini, biaya relatif dari setiap panggilan fungsi bisa sangat tinggi.
Dan bahkan dalam bahasa yang dinamis, seperti Ruby atau Python, memiliki metode pendek juga membantu dalam optimasi kompiler juga. Dalam bahasa dinamis, semakin 'dinamis' suatu fitur, semakin sulit untuk dioptimalkan. Misalnya, metode panjang yang mengambil X dan dapat mengembalikan Int, Float, atau String kemungkinan akan melakukan jauh lebih lambat daripada tiga metode terpisah yang masing-masing hanya mengembalikan satu jenis. Ini karena, jika kompiler tahu persis jenis fungsi apa yang akan kembali, ia dapat mengoptimalkan fungsi situs panggilan juga. (Misalnya, tidak memeriksa konversi tipe.)
sumber
Ini sangat tergantung pada apa yang ada dalam kode.
Saya telah melihat rutinitas ribuan baris yang tidak ada masalah dengan saya. Itu adalah pernyataan switch yang sangat besar, tidak ada opsi yang melebihi selusin baris dan satu-satunya struktur kontrol dalam opsi apa pun adalah satu loop. Saat ini akan ditulis dengan objek tapi itu bukan pilihan saat itu.
Saya juga melihat 120 garis di saklar di depan saya. Tidak ada case melebihi 3 baris - seorang penjaga, sebuah tugas dan istirahat. Ini mem-parsing file teks, objek tidak mungkin. Alternatif apa pun akan lebih sulit dibaca.
sumber
Kebanyakan kompiler tidak mempermasalahkan panjang fungsi. Suatu fungsi harus fungsional, tetapi keduanya mudah dipahami, diubah, dan digunakan kembali oleh manusia. Pilih panjang yang paling cocok untuk Anda.
sumber
Aturan umum saya adalah bahwa suatu fungsi harus sesuai di layar. Hanya ada tiga kasus yang saya temukan yang cenderung melanggar ini:
1) Fungsi pengiriman. Di masa lalu ini adalah umum tetapi kebanyakan dari mereka diganti dengan benda warisan hari ini. Objek hanya bekerja di dalam program Anda, dan dengan demikian Anda akan tetap melihat fungsi pengiriman sesekali ketika berhadapan dengan data yang datang dari tempat lain.
2) Fungsi yang melakukan sejumlah langkah untuk mencapai tujuan dan di mana langkah-langkah tersebut tidak memiliki pembagian yang baik. Anda berakhir dengan fungsi yang hanya memanggil daftar panjang fungsi lainnya secara berurutan.
3) Suka # 2 tetapi di mana langkah-langkah individu sangat kecil sehingga mereka hanya sebaris daripada dipanggil secara terpisah.
sumber
Mungkin panjang fungsi tidak jadi metrik yang baik. Kami mencoba menggunakan kompleksitas siklomatik , pada metode juga, dan salah satu aturan check-in kontrol sumber masa depan bahwa kompleksitas siklomatik pada kelas dan metode harus lebih rendah dari X.
Untuk metode, X diatur ke 30, dan itu cukup ketat.
sumber