Apakah metode lama selalu buruk? [Tutup]


64

Jadi melihat-lihat sebelumnya saya perhatikan beberapa komentar tentang metode panjang menjadi praktik yang buruk.

Saya tidak yakin saya selalu setuju bahwa metode panjang itu buruk (dan ingin pendapat dari orang lain).

Sebagai contoh, saya memiliki beberapa pandangan Django yang melakukan sedikit pemrosesan objek sebelum mengirimnya ke tampilan, metode yang panjang berupa 350 baris kode. Saya memiliki kode saya yang ditulis sehingga berkaitan dengan parameter - menyortir / memfilter queryset, kemudian sedikit demi sedikit melakukan beberapa pemrosesan pada objek permintaan saya telah kembali.

Jadi pemrosesan adalah agregasi kondisional, yang memiliki aturan yang cukup rumit sehingga tidak dapat dengan mudah dilakukan dalam database, jadi saya memiliki beberapa variabel yang dideklarasikan di luar loop utama kemudian diubah selama loop.

variable_1 = 0
variable_2 = 0
for object in queryset :
     if object.condition_condition_a and variable_2 > 0 :
     variable 1+= 1
     .....
     ...    
     . 
      more conditions to alter the variables

return queryset, and context 

Jadi menurut teori saya harus memfaktorkan semua kode menjadi metode yang lebih kecil, sehingga saya memiliki metode tampilan sebagai maksimum satu halaman.

Namun setelah bekerja pada berbagai basis kode di masa lalu, kadang-kadang saya menemukan itu membuat kode kurang mudah dibaca, ketika Anda harus terus-menerus melompat dari satu metode ke metode berikutnya mencari tahu semua bagian itu, sambil tetap menjaga metode terluar di kepala Anda.

Saya menemukan bahwa memiliki metode panjang yang diformat dengan baik, Anda dapat melihat logikanya dengan lebih mudah, karena tidak disembunyikan dalam metode batin.

Saya dapat memfaktorkan kode ke dalam metode yang lebih kecil, tetapi sering kali ada loop dalam yang digunakan untuk dua atau tiga hal, sehingga akan menghasilkan kode yang lebih kompleks, atau metode yang tidak melakukan satu hal kecuali dua atau tiga (alternatifnya) Saya bisa mengulangi loop batin untuk setiap tugas, tetapi kemudian akan ada hit kinerja).

Jadi adakah kasus bahwa metode panjang tidak selalu buruk? Apakah selalu ada kasus untuk metode menulis, ketika mereka hanya akan digunakan di satu tempat?

UPDATE: Sepertinya saya menanyakan pertanyaan ini lebih dari setahun yang lalu.

Jadi saya refactored kode setelah respon (campur) di sini, membaginya menjadi metode. Ini adalah aplikasi Django yang mengambil set kompleks objek terkait dari database, jadi argumen pengujiannya keluar (mungkin akan menghabiskan sebagian besar tahun ini untuk membuat objek yang relevan untuk kasus uji. Saya memiliki tipe "ini perlu dilakukan kemarin" lingkungan kerja sebelum ada yang mengeluh). Memperbaiki bug pada bagian kode itu sedikit lebih mudah sekarang, tetapi tidak secara masif.

sebelum :

#comment 1 
bit of (uncomplicated) code 1a  
bit of code 2a

#comment 2 
bit of code 2a
bit of code 2b
bit of code 2c

#comment 3
bit of code 3

sekarang:

method_call_1
method_call_2
method_call_3

def method_1 
    bit of (uncomplicated) code 1a  
    bit of code 2a

def method_2 
    bit of code 2a
    bit of code 2b
    bit of code 2c

def method_3
    bit of code 3

156
Semua yang absolut itu buruk. Selalu.
Joachim Sauer

30
Saya melihat argumen "ekstrak metode jika Anda dapat menggunakannya kembali" cukup sering (dalam bentuk ini atau yang serupa), tetapi saya tidak membelinya: jika metode ini melakukan lebih dari satu hal, Anda harus mengekstrak metode dari itu agar mudah dibaca / pemeliharaan bahkan jika metode-metode baru dipanggil dari satu tempat di kode Anda.
Joachim Sauer

4
@gnat: wow, bukankah semacam inlining manual (melalui preprocessor) di build-step akan menjadi solusi yang lebih baik di sini?
Joachim Sauer

11
Salah satu programmer terbaik yang saya tahu berkomentar bahwa jika Anda benar-benar menginginkan ukuran, jumlah variabel lokal lebih baik daripada panjang sebenarnya. Dia sedang mengerjakan pengoptimal jalur yang rumit di mana nyali adalah satu metode yang panjangnya beberapa ratus baris, tetapi jumlah status (variabel lokal) yang disimpan sangat kecil.
Chuu

2
Metode panjang tidak selalu buruk; tetapi mereka adalah sesuatu yang harus selalu Anda lihat dan tanyakan pada diri sendiri "apakah ini buruk?"
Carson63000

Jawaban:


80

Tidak, metode panjang tidak selalu buruk.

Dalam buku Code Complete , diukur bahwa metode yang panjang terkadang lebih cepat dan lebih mudah untuk ditulis, dan tidak mengarah ke masalah pemeliharaan.

Padahal, yang benar-benar penting adalah tetap KERING dan menghormati pemisahan kekhawatiran. Kadang-kadang, perhitungannya hanya panjang untuk ditulis, tetapi benar-benar tidak akan menyebabkan masalah di masa depan.

Namun, dari pengalaman pribadi saya, metode yang paling panjang cenderung tidak memiliki pemisahan perhatian. Sebenarnya, metode panjang adalah cara mudah untuk mendeteksi bahwa ada sesuatu yang mungkin salah dalam kode, dan bahwa perawatan khusus diperlukan di sini saat melakukan peninjauan kode.

EDIT: Saat komentar dibuat, saya menambahkan poin menarik pada jawabannya. Saya sebenarnya juga akan memeriksa metrik kompleksitas untuk fungsi (NPATH, kompleksitas siklomatik atau CRAP yang lebih baik).

Bahkan, saya sarankan untuk tidak memeriksa metrik tersebut pada fungsi yang panjang, tetapi untuk memasukkan peringatan pada mereka dengan alat otomatis (misalnya checkstyle untuk java misalnya) PADA SETIAP FUNGSI.


41
+1: "Tidak, metode panjang tidak selalu buruk" tetapi hampir selalu buruk
Binary Worrier

67
Badan metode panjang adalah bau kode klasik : itu sendiri tidak masalah, tapi itu indikasi bahwa mungkin ada masalah di sana.
Joachim Sauer

6
+1, tetapi saya masih merekomendasikan untuk memeriksa kompleksitas siklomatik dari metode yang panjang. Nilai-nilai tinggi menunjukkan metode yang secara efektif tidak mungkin untuk unit test (dan metode panjang sangat jarang tanpa logika aliran kontrol).
Daniel B

11
Saya menggunakan nama metode untuk meminimalkan komentar. Yang terkadang mengarah ke hal-hal seperti "getSelectedNodeWithChildren", tetapi rekan saya terus mengatakan kepada saya, bahwa kode saya dapat dibaca dengan baik. Saya juga mencoba menghindari singkatan, itu bagus untuk ditulis, tetapi tidak begitu bagus untuk dibaca.
K ..

4
@ da_b0uncer Itu juga kebijakan yang saya ikuti. Lebih sulit untuk membaca kode daripada menulisnya, jadi upaya ekstra saat menulis untuk membuat kode lebih mudah dibaca memang membuahkan hasil.
deadalnix

55

Sebagian besar fokus di sini tampaknya berada di sekitar kata selalu . Ya, absolut itu buruk, dan rekayasa perangkat lunak hampir sama seninya dengan sains, dan semua itu ... tapi saya harus mengatakan bahwa untuk contoh yang Anda berikan, metode ini akan lebih baik jika dibagi naik. Ini adalah argumen yang biasanya saya gunakan untuk membenarkan pemisahan metode Anda:

Keterbacaan: Saya tidak yakin tentang yang lain, tetapi saya tidak bisa membaca 350 baris kode dengan cepat. Ya, jika itu kode saya sendiri , dan saya bisa membuat banyak asumsi tentang hal itu, saya bisa membaca dengan sangat cepat, tapi itu intinya. Pertimbangkan seberapa mudah metode itu dibaca, jika terdiri dari 10 panggilan ke metode lain (masing-masing dengan nama deskriptif). Melakukan ini, Anda telah memperkenalkan layering dalam kode, dan metode tingkat tinggi memberikan garis besar, manis kepada pembaca mengenai apa yang terjadi.

Sunting - untuk menjelaskan hal itu, pikirkan seperti ini: bagaimana Anda menjelaskan metode itu kepada anggota tim baru? Tentunya ia memiliki beberapa struktur yang dapat Anda rangkum di sepanjang garis "well, ini dimulai dengan melakukan A, lalu B, lalu terkadang C, dll". Memiliki metode "ikhtisar" singkat yang memanggil metode lain membuat struktur ini jelas. Sangat jarang menemukan 350 baris kode yang tidak menguntungkan; otak manusia tidak dimaksudkan untuk berurusan dengan daftar 100-an item, kami mengelompokkannya.

Dapat digunakan kembali: Metode panjang cenderung memiliki kohesi yang rendah - mereka sering melakukan lebih dari satu hal. Kohesi rendah adalah musuh penggunaan kembali; jika Anda menggabungkan beberapa tugas menjadi satu metode, metode ini akan berakhir digunakan kembali di tempat yang lebih sedikit dari yang seharusnya.

Testabilitas dan kohesi: Saya menyebutkan kompleksitas siklomatik dalam komentar di atas - ini adalah ukuran yang cukup baik tentang seberapa kompleks metode Anda. Ini mewakili batas bawah jumlah jalur unik melalui kode Anda, tergantung pada input (edit: dikoreksi sesuai komentar MichaelT). Ini juga berarti bahwa untuk menguji metode Anda dengan benar, Anda harus memiliki sedikitnya kasus uji sebanyak jumlah kompleksitas siklomatik Anda. Sayangnya, ketika Anda mengumpulkan potongan-potongan kode yang tidak benar-benar bergantung satu sama lain, tidak ada cara untuk memastikan kurangnya ketergantungan ini, dan kompleksitasnya cenderung bertambah banyak. Anda dapat menganggap ukuran ini sebagai indikasi jumlah hal berbeda yang ingin Anda lakukan. Jika terlalu tinggi, saatnya untuk memecah belah dan menaklukkan.

Refactoring dan struktur: Metode panjang sering merupakan pertanda bahwa beberapa struktur kurang dalam kode. Seringkali, pengembang tidak dapat menemukan kesamaan antara bagian-bagian yang berbeda dari metode itu, dan di mana garis dapat ditarik di antara mereka. Menyadari bahwa metode yang panjang adalah masalah, dan mencoba membaginya menjadi metode yang lebih kecil adalah langkah pertama di jalan yang lebih panjang untuk benar-benar mengidentifikasi struktur yang lebih baik untuk semuanya. Mungkin Anda perlu membuat satu atau dua kelas; pada akhirnya tidak akan menjadi lebih kompleks!

Saya juga berpikir bahwa dalam kasus ini, alasan untuk memiliki metode yang panjang adalah "... beberapa variabel yang dideklarasikan di luar loop utama kemudian diubah selama loop". Saya bukan ahli tentang Python, tapi saya cukup yakin bahwa masalah ini bisa diperbaiki oleh beberapa bentuk lewat referensi.


13
1 karena menolak selalu bagian dari pertanyaan dan berfokus pada daging: Apakah metode lama atau tidak itu buruk. Saya pikir OP sedang mencari pembenaran seolah-olah skenarionya adalah kasus tepi, meskipun biasanya ketika saya mendengar orang-orang menjelaskan praktik buruk yang diperlukan untuk skenario yang tidak biasa, itu hanya karena mereka tidak berusaha sangat keras untuk menggunakan praktik yang baik. Skenario yang tidak biasa benar-benar sangat tidak biasa, metode yang panjang sayangnya namun cukup umum.
Jimmy Hoffa

2
OK melihat daftar di atas: keterbacaan saya akan mengatakan dari pengalaman masa lalu meningkat dengan memiliki metode lebih lama, mengandung banyak komentar, dan diformat dengan baik, daripada harus melompat tentang kode dari metode ke metode Meskipun ini mungkin cukup subjektif. Saya tidak berharap bagian dari kode akan digunakan kembali. Sebagian besar penggunaan kembali kode diperoleh dari warisan saat ini.
wobbily_col

1
@wobbily_col BTW, jika Anda mencari teks yang ditulis dengan baik dengan alasan memiliki metode yang lebih pendek, bacalah beberapa bab pertama dari Kode Bersih , yang melakukan pekerjaan penjelasan dengan cukup baik.
Daniel B

5
@wobbily_col Anda mengatakan bahwa harus melompat-lompat terlalu banyak untuk memahami kode dengan banyak metode membingungkan, saya pikir titik yang hilang di sini adalah pentingnya penamaan. Jika suatu metode dinamai dengan baik, Anda tidak perlu melihatnya untuk mengetahui apa yang dilakukannya, metode pemanggilan harus benar-benar dapat dipahami tanpa pengetahuan mendasar tentang apa yang disebut metode itu lakukan, misalnya apakah Anda pernah menggunakan someVar.toString()dan merasakan Anda perlu melihat kode toString untuk mengetahui apa yang dilakukannya? Anda baru saja membaca melewatinya karena penamaan metode yang baik.
Jimmy Hoffa

4
Di samping catatan, memiliki metode yang membutuhkan n parameter juga merupakan bau kode dan menunjukkan bahwa metode tersebut dapat melakukan lebih dari satu hal. Hal yang sama berlaku untuk memiliki metode yang sulit disebutkan. Dan jika benar-benar membutuhkan semua parameter itu, mereka biasanya merupakan bagian dari konsep yang lebih besar, yang dapat dan harus dilampirkan dalam kelas tersendiri. Tentu saja, kita bisa memberikan contoh yang lebih baik tidak menggunakan aturan ini - maksud saya adalah jika Anda melihat metode seperti itu, selidiki secara menyeluruh, itu mungkin buruk dalam beberapa hal.
KL

28

Metode panjang selalu buruk, tetapi terkadang lebih baik daripada alternatifnya.


5
tanpa penjelasan, jawaban ini dapat menjadi sia-sia jika ada orang yang memposting pendapat yang berbeda. Misalnya, jika seseorang memposting klaim seperti "Metode panjang tidak pernah buruk, tetapi kadang-kadang lebih buruk daripada alternatifnya." , bagaimana jawaban ini membantu pembaca untuk memilih dua pendapat yang bertentangan? Pertimbangkan untuk mengeditnya menjadi bentuk yang lebih baik
agas

9

Metode panjang adalah bau kode . Mereka biasanya menunjukkan bahwa ada sesuatu yang salah, tetapi itu bukan aturan yang sulit dan cepat. Biasanya, kasus-kasus di mana mereka dibenarkan melibatkan banyak negara dan aturan bisnis yang cukup kompleks (seperti yang Anda temukan).

Mengenai pertanyaan Anda yang lain, sering kali membantu untuk memisahkan potongan-potongan logika menjadi metode-metode terpisah, bahkan jika mereka hanya dipanggil sekali. Itu membuatnya lebih mudah untuk melihat logika tingkat tinggi dan dapat membuat pengecualian menangani sedikit lebih bersih. Asalkan Anda tidak harus memasukkan dua puluh parameter untuk mewakili status pemrosesan!


7

Metode panjang tidak selalu buruk. Mereka biasanya merupakan tanda bahwa mungkin ada masalah.

Pada sistem yang saya kerjakan kami memiliki sekitar setengah lusin metode yang panjangnya lebih dari 10.000 baris. Satu saat ini panjangnya 54.830 baris. Dan tidak apa-apa.

Fungsi-fungsi yang sangat panjang ini sangat sederhana dan dibuat otomatis. Monster 54,830 garis panjang besar itu berisi data gerakan kutub harian dari 1 Januari 1962 hingga 10 Januari 2012 (rilis terakhir kami). Kami juga merilis prosedur di mana pengguna kami dapat memperbarui file yang dibuat otomatis itu. File sumber itu berisi data gerakan kutub dari http://data.iers.org/products/214/14443/orig/eopc04_08_IAU2000.62- sekarang , diterjemahkan secara otomatis ke C ++.

Membaca situs web tersebut dengan cepat tidak dimungkinkan dalam pemasangan yang aman. Tidak ada koneksi ke dunia luar. Mengunduh situs web sebagai salinan lokal dan mem-parsing dalam C ++ juga bukan pilihan; parsing lambat , dan ini harus cepat. Mengunduh, menerjemahkan otomatis ke C ++, dan mengkompilasi: Sekarang Anda memiliki sesuatu yang cepat. (Hanya saja jangan mengkompilasinya dioptimalkan. Sungguh menakjubkan berapa lama kompiler pengoptimal yang dibutuhkan untuk mengkompilasi 50.000 baris kode garis lurus sangat sederhana. Dibutuhkan lebih dari setengah jam di komputer saya untuk mengkompilasi satu file yang dioptimalkan. Dan pengoptimalan tidak menghasilkan apa-apa sama sekali. Tidak ada yang dioptimalkan. Ini kode garis lurus sederhana, satu pernyataan tugas setelah yang lain.)


6
"satu pernyataan penugasan demi satu" ... Saya akan menyebutnya "file data". Mengapa itu kode?
Joachim Sauer

3
@ JoachimSauer - Karena mem-parsing file data besar pada saat dijalankan dalam pengaturan Monte Carlo adalah ide yang buruk. Ide yang sangat, sangat buruk.
David Hammen

4
@ Davidvidam: kemudian lakukan pada waktu inisialisasi, sama seperti Anda memaksa linker / loader Anda lakukan. Atau tulis file data sebagai struktur C di file header, alih-alih kode C. Setidaknya kemudian loader akan dimuat sebagai blok data.
Javier

3
@ Javier: Bahkan pada saat inisialisasi itu bisa menjadi ide yang sangat buruk, setidaknya dalam pengaturan Monte Carlo. Simulasi yang membutuhkan beberapa menit untuk diinisialisasi, tetapi hanya beberapa detik untuk berjalan bertentangan dengan keinginan mendapatkan puluhan ribu proses dalam semalam. Mengubah tugas waktu inisialisasi kunci untuk mengkompilasi tugas waktu memperbaiki masalah itu. Kami telah mencoba sejumlah teknik, termasuk pendekatan struktur data yang dikompilasi. Itu hanya tidak berfungsi atau akan sangat sulit untuk membuat pekerjaan dalam beberapa kasus (misalnya, model gravitasi besar). Pendekatan kode garis lurus mudah dibuat otomatis, mudah diverifikasi. Itu hanya kode jelek.
David Hammen

7
+1 kisah menarik. kode yang dihasilkan tidak benar-benar kode sumber sehingga orang dapat berargumen bahwa ini tidak 'melanggar' aturan. kita menganggap generator kode itu sendiri memiliki metode pendek yang bagus
jk.

7

Katakan saja ada cara yang baik dan buruk untuk memecah metode yang panjang. Harus "[menyimpan] metode terluar di kepala Anda" adalah tanda bahwa Anda tidak memecahnya dengan cara yang paling optimal, atau bahwa submethods Anda diberi nama yang buruk. Secara teori, ada contoh di mana metode panjang lebih baik. Dalam praktiknya, ini sangat jarang. Jika Anda tidak dapat menemukan cara membuat metode yang lebih pendek dapat dibaca, mintalah seseorang untuk meninjau kode Anda, dan minta mereka secara khusus untuk gagasan tentang memperpendek metode.

Adapun beberapa loop yang menyebabkan kinerja seharusnya, tidak ada cara untuk mengetahui itu tanpa mengukur. Beberapa loop yang lebih kecil dapat secara signifikan lebih cepat jika itu berarti semua yang dibutuhkannya dapat tetap dalam cache. Bahkan jika ada hit kinerja, biasanya diabaikan demi keterbacaan.

Saya akan mengatakan bahwa seringkali metode yang panjang lebih mudah untuk ditulis , meskipun metode itu lebih sulit dibaca . Itu sebabnya mereka berkembang biak meskipun tidak ada yang menyukainya. Tidak ada yang salah dengan perencanaan dari awal hingga refactor sebelum Anda memeriksanya.


1
"Tidak ada yang salah dengan perencanaan dari awal hingga refactor sebelum kamu memeriksanya." +1 untuk itu. Sebagian besar IDE saat ini memiliki alat refactoring yang membuatnya sangat mudah juga. Tetapi ada metode terbalik di mana Anda mendelegasikan hal-hal ke fungsi yang tidak ada, dan kemudian pergi dan mengisi metode, tapi saya tidak pernah bisa kode seperti itu, sebanyak yang saya coba.
Tjaart

+1 untuk "Harus" [menyimpan] metode terluar di kepala Anda "adalah tanda bahwa Anda tidak akan memecahnya dengan cara yang paling optimal,"
Michael Shaw

4

Metode panjang bisa lebih komputasional dan hemat ruang, bisa lebih mudah untuk melihat logika dan lebih mudah untuk men-debug mereka. Namun aturan ini hanya benar-benar berlaku ketika hanya satu programmer yang menyentuh kode itu. Kode ini akan menjadi sakit untuk diperluas jika bukan atom, pada dasarnya orang berikutnya harus mulai dari awal dan kemudian men-debug dan menguji ini akan berlangsung selamanya karena tidak menggunakan kode yang dikenal baik.


34
Setidaknya selalu ada dua programmer yang terlibat: "Anda" dan "Anda, tiga minggu dari sekarang".
Joachim Sauer

3

Ada sesuatu yang kami sebut Dekomposisi Fungsional yang menyiratkan untuk memecah metode Anda yang lebih panjang menjadi metode yang lebih kecil sedapat mungkin. Seperti yang Anda sebutkan bahwa metode Anda melibatkan penyortiran / penyaringan maka Anda lebih baik memiliki metode atau fungsi terpisah untuk tugas-tugas ini.

Tepatnya, metode Anda harus difokuskan hanya pada 1 tugas saja.

Dan jika perlu memanggil metode lain karena beberapa alasan maka lakukan sebaliknya melanjutkan dengan yang sudah Anda tulis. Juga untuk pruposis keterbacaan, Anda dapat menambahkan komentar. Secara konvensional, programmer menggunakan komentar multi-line (/ ** / dalam C, C ++, C # dan Java) untuk deskripsi metode dan menggunakan komentar single-line (// dalam C, C ++, C # dan Java). Ada juga alat dokumentasi yang baik tersedia untuk keterbacaan kode yang lebih besar (mis. JavaDoc ). Anda juga dapat melihat komentar berbasis XML jika Anda adalah pengembang .Net.

Loop mempengaruhi kinerja program dan dapat menyebabkan overhead aplikasi jika tidak digunakan dengan benar. Idenya adalah untuk merancang algoritma Anda sedemikian rupa sehingga Anda menggunakan loop bersarang sesedikit mungkin.


Juga dikenal sebagai "Fungsi harus melakukan SATU HAL."
lorddev

3

Tidak apa-apa menulis fungsi yang panjang. Tetapi itu bervariasi pada konteks apakah Anda benar-benar membutuhkan atau tidak. Untuk misalnya beberapa algorthms terbaik dinyatakan terbaik ketika suatu bagian. Di sisi lain, sebagian besar rutin dalam program berorientasi objek akan menjadi rutinitas accessor, yang akan sangat singkat. Beberapa rutin pemrosesan yang panjang yang memiliki sakelar yang panjang, jika kondisinya dapat dioptimalkan melalui metode yang digerakkan oleh tabel.

Ada diskusi singkat yang sangat baik dalam Kode Lengkap 2 tentang panjang rutinitas.

Panjang maksimum terbaik 497 teoritis sering digambarkan sebagai satu atau dua halaman daftar program, 66 hingga 132 baris. Program modern cenderung memiliki volume rutinitas yang sangat pendek dicampur dengan rutinitas yang lebih lama.

Beberapa dekade bukti mengatakan bahwa rutinitas dengan panjang seperti itu tidak lebih rentan kesalahan daripada rutinitas yang lebih pendek. Biarkan masalah seperti kedalaman bersarang, jumlah variabel, dan pertimbangan terkait kompleksitas lainnya menentukan panjang rutin daripada memaksakan panjang

Jika Anda ingin menulis rutinitas lebih lama dari sekitar 200 baris, berhati-hatilah. Tak satu pun dari studi yang melaporkan penurunan biaya, penurunan tingkat kesalahan, atau keduanya dengan rutinitas yang lebih besar dibedakan antara ukuran lebih besar dari 200 baris, dan Anda pasti akan mengalami batas pemahaman yang lebih tinggi ketika Anda melewati 200 baris kode. 536 pembatasan per se.


2

Suara lain yang hampir selalu salah. Saya menemukan dua kasus dasar di mana itu adalah jawaban yang tepat, meskipun:

1) Suatu metode yang pada dasarnya hanya memanggil banyak metode lain dan tidak melakukan pekerjaan nyata itu sendiri. Anda memiliki proses yang membutuhkan 50 langkah untuk diselesaikan, Anda mendapatkan metode dengan 50 panggilan di dalamnya. Biasanya tidak ada yang bisa diperoleh dengan mencoba memecahnya.

2) Dispatcher. Desain OOP telah menghilangkan sebagian besar metode tersebut tetapi sumber data yang masuk pada dasarnya adalah data saja dan dengan demikian tidak dapat mengikuti prinsip-prinsip OOP. Bukan hal yang aneh untuk memiliki semacam rutin dispatcher dalam kode yang menangani data.

Saya juga akan mengatakan bahwa seseorang seharusnya tidak mempertimbangkan pertanyaan ketika berhadapan dengan hal-hal yang di-autogenerasi. Tidak ada yang mencoba memahami apa yang dilakukan kode autogenerated, tidak ada artinya sedikitpun apakah mudah bagi manusia untuk mengerti.


1
Proses 50 langkah mungkin dapat diringkas menjadi beberapa ember melalui. Langkah 1 - 9 adalah pemeriksaan parameter, jadi buat metode baru yang disebut pemeriksaan parameter. (Saya yakin ada beberapa contoh di mana ini tidak mungkin. Saya akan tertarik melihatnya).
sixtyfootersdude

@sixtyfootersdude: Tentu, Anda bisa memecahnya. Saya tidak mengatakan itu tidak mungkin, saya mengatakan tidak ada yang bisa diperoleh dengan memecahnya. Meskipun bukan 50 langkah, saya telah mencapai sesuatu seperti itu: Menciptakan dunia game. # 1 menciptakan dunia kosong, # 2 menciptakan medan dan kemudian sejumlah langkah setelah itu memijatnya dengan satu atau lain cara.
Loren Pechtel

& sixtyfootersdude: Sungguh menakjubkan bagaimana Anda tahu kode yang belum pernah Anda lihat dan bagaimana memperbaikinya.
gnasher729

2

Saya ingin membahas contoh yang Anda berikan:

Sebagai contoh, saya memiliki beberapa pandangan Django yang melakukan sedikit pemrosesan objek sebelum mengirimnya ke tampilan, metode yang panjang berupa 350 baris kode. Saya memiliki kode saya ditulis sehingga berkaitan dengan paramaters - menyortir / memfilter queryset, kemudian sedikit demi sedikit melakukan beberapa pemrosesan pada objek permintaan saya telah kembali.

Di perusahaan saya, proyek terbesar kami dibangun di Django dan kami juga memiliki fungsi tampilan panjang (banyak lebih dari 350 baris). Saya berpendapat bahwa kita tidak perlu selama itu, dan mereka menyakiti kita.

Fungsi tampilan ini melakukan banyak pekerjaan terkait longgar yang harus diekstraksi ke model, kelas helper, atau fungsi helper. Selain itu, kami akhirnya menggunakan kembali pandangan untuk melakukan hal-hal yang berbeda, yang sebaliknya harus dibagi menjadi pandangan yang lebih kohesif.

Saya menduga pandangan Anda memiliki karakteristik serupa. Dalam kasus saya, saya tahu itu menyebabkan masalah dan saya sedang bekerja untuk membuat perubahan. Jika Anda tidak setuju bahwa itu menyebabkan masalah, maka Anda tidak perlu memperbaikinya.


2

Saya tidak tahu apakah seseorang telah menyebutkan ini, tetapi salah satu alasan mengapa metode yang lama itu buruk adalah karena mereka biasanya melibatkan beberapa tingkat abstraksi yang berbeda. Anda memiliki variabel lingkaran dan segala macam hal terjadi. Pertimbangkan fungsi fiktif:

function nextSlide() {
  var content = getNextSlideContent();
  hideCurrentSlide();
  var newSlide = createSlide(content);
  setNextSlide(newSlide);
  showNextSlide();
}

Jika Anda melakukan semua animasi, perhitungan, akses data dll dalam fungsi itu akan berantakan. Fungsi nextSlide () menjaga lapisan abstraksi yang konsisten (sistem slide state) dan mengabaikan yang lain. Ini membuat kode dapat dibaca.

Jika Anda harus terus-menerus melangkah ke metode yang lebih kecil untuk melihat apa yang mereka lakukan, maka upaya membagi fungsi gagal. Hanya karena kode yang Anda baca tidak melakukan hal-hal yang jelas dalam metode anak tidak berarti metode anak adalah ide yang buruk, hanya saja itu dilakukan secara tidak benar.

Ketika saya membuat metode, saya biasanya membaginya menjadi metode yang lebih kecil sebagai semacam strategi membagi dan menaklukkan. Metode seperti

   if (hasMoreRecords()) { ... }

tentu lebih mudah dibaca daripada

if (file.isOpen() && i < recordLimit && currentRecord != null) { ... } 

Baik?

Saya setuju tentang pernyataan absolut yang buruk dan juga setuju bahwa biasanya metode yang panjang itu buruk.


1

Kisah nyata. Saya pernah menemukan metode yang panjangnya lebih dari dua ribu baris. Metode ini memiliki daerah yang menggambarkan apa yang dilakukannya di daerah tersebut. Setelah membaca suatu wilayah, saya memutuskan untuk melakukan metode ekstrak otomatis, menamainya sesuai dengan nama wilayah. pada saat saya selesai, metode itu tidak lebih dari 40 metode panggilan masing-masing sekitar lima puluh baris dan semuanya bekerja sama.

Apa yang terlalu besar itu subjektif. Terkadang, suatu metode tidak dapat dipecah lebih jauh dari apa yang ada saat ini. Ini seperti menulis buku. Kebanyakan orang setuju bahwa paragraf panjang biasanya harus dibagi. Tetapi kadang-kadang, hanya ada satu ide dan membaginya menyebabkan lebih banyak kebingungan daripada yang disebabkan oleh panjangnya paragraf itu.


0

Inti dari suatu metode adalah membantu mengurangi regurgitasi kode. Suatu metode harus memiliki fungsi spesifik yang menjadi tanggung jawabnya. Jika Anda akhirnya mengulangi kode di banyak tempat Anda berisiko kode memiliki hasil yang tidak terduga jika spesifikasi perangkat lunak yang dirancang untuk alamat diubah.

Untuk metode yang memiliki 350 baris akan menyarankan bahwa banyak tugas yang sedang dilakukan direplikasi di tempat lain karena tidak biasa untuk membutuhkan sejumlah besar kode untuk melakukan tugas khusus.


Bantu mengurangi kode apa ?
Avner Shahar-Kashtan

@ AvnerShahar-Kashtan, dia mungkin berarti "duplikasi" :-)
Péter Török

0

Ini bukan metode panjang yang merupakan praktik buruk, tetapi lebih membuat mereka seperti itu yang buruk.

Maksud saya tindakan aktual refactoring sampel Anda dari:

varaible_1 = 0
variable_2 = 0
for object in queryset :
     if object.condition_condition_a and variable_2 > 0 :
     variable 1+= 1
     .....
     ...    
     . 
      more conditions to alter the variables

return queryset, and context 

untuk

Status status = new Status();
status.variable1 = 0;
status.variable2 = 0;
for object in queryset :
     if object.condition_condition_a and status.variable2 > 0 :
     status.variable1 += 1
     .....
     ...    
     . 
      more conditions to alter the variables (status)

return queryset, and context 

lalu ke

class Status {
    variable1 = 0;
    variable2 = 0;

    void update(object) {
        if object.condition_condition_a and variable2 > 0 {
            variable1 += 1
        }
    }
};

Status status = new Status();
for object in queryset :
     status.update(object);
     .....
     ...    
     . 
      more conditions to alter the variables (status)

return queryset, and context 

Anda sekarang dalam perjalanan menuju bukan hanya metode yang jauh lebih pendek tetapi jauh lebih bisa digunakan dan dimengerti.


0

Saya pikir fakta bahwa metode ini sangat panjang adalah sesuatu untuk diperiksa, tapi jelas bukan anti-pola instan. Hal besar yang harus dicari dalam metode besar adalah banyak bersarang. Jika Anda memiliki

foreach(var x in y)
{
    //do ALL the things
    //....
}

dan badan loop tidak terlalu terlokalisasi (yaitu, Anda bisa mengirimkannya kurang dari 4 parameter), maka mungkin lebih baik untuk mengubahnya menjadi:

foreach(var x in y)
{
    DoAllTheThings(x);
}
...
void DoAllTheThings(object x)
{
    //do ALL the things
    //....
}

Pada gilirannya, ini dapat sangat mengurangi panjang fungsi. Juga, pastikan untuk mencari kode duplikat dalam fungsi dan memindahkannya ke fungsi yang terpisah

Akhirnya, beberapa metode hanya panjang dan rumit dan tidak ada yang dapat Anda lakukan. Beberapa masalah memerlukan solusi yang tidak mudah dikodekan. Sebagai contoh, menguraikan tata bahasa dengan banyak kompleksitas dapat membuat metode yang sangat panjang yang benar-benar tidak dapat Anda lakukan tanpa membuatnya lebih buruk.


0

Sebenarnya, itu tergantung. Seperti disebutkan, jika kode tidak memisahkan masalah dan mencoba melakukan segalanya dalam satu metode, maka ini merupakan masalah. Memisahkan kode menjadi beberapa modul membuatnya lebih mudah untuk membaca kode, serta menulis kode (oleh banyak programmer). Mengikuti satu modul (kelas) per file sumber adalah ide yang baik untuk memulai.

Kedua, ketika datang ke fungsi / prosedur:

void setDataValueAndCheckForRange(Data *data) {/*code*/} 

adalah metode yang baik jika memeriksa kisaran hanya "Data". Ini adalah metode BAD ketika rentang yang sama berlaku untuk beberapa fungsi (contoh kode buruk):

void setDataValueAndCheckForRange(Data *data){ /*code */}
void addDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}
void subDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}
void mulDataValuesAndCheckForRange(Data *result, Data *d1, Data *d2){ /*code*/}

Ini harus di refactored untuk:

bool isWithinRange(Data *d){ /*code*/ }
void setDataValue(Data *d) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void addDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void subDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 
void mulDataValue(Data *d, Data *d1, Data *d2) {/*code*/ if(isWithinRange(d)){/*continue*/}else{/*warn/abort*/} 

Gunakan kembali kode sebanyak mungkin. Dan itu mungkin ketika setiap fungsi program Anda SEDERHANA (tidak harus mudah) cukup.

QUOTE: GUNUNG terdiri dari butiran kecil bumi. Lautan terdiri dari tetesan kecil air .. (- Sivananda)


0

Metode panjang cenderung ke arah "buruk" dalam bahasa imperatif yang mendukung pernyataan, efek samping, dan mutabilitas, justru karena fitur-fitur itu meningkatkan kompleksitas dan dengan demikian bug.

Dalam bahasa pemrograman fungsional, yang mendukung ekspresi, kemurnian, dan kekekalan, ada sedikit alasan untuk khawatir.

Dalam bahasa fungsional dan imperatif, selalu terbaik untuk memfaktorkan potongan kode yang dapat digunakan kembali ke dalam rutinitas tingkat atas yang umum, tetapi dalam bahasa fungsional yang mendukung pelingkupan leksikal dengan fungsi bersarang dll., Sebenarnya enkapsulasi yang lebih baik untuk menyembunyikan sub-rutin di bagian atas. -tingkat fungsi (metode) daripada memecahnya menjadi fungsi tingkat atas lainnya.


Namun, dalam bahasa fungsional, metode panjang jauh lebih jarang.
kuncinya
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.