Setiap kali saya menemukan diri saya menulis logika yang sama lebih dari sekali, saya biasanya menempelkannya pada suatu fungsi sehingga hanya ada satu tempat di aplikasi saya, saya harus mempertahankan logika itu. Efek sampingnya adalah saya kadang-kadang berakhir dengan satu atau dua fungsi garis seperti:
function conditionMet(){
return x == condition;
}
ATAU
function runCallback(callback){
if($.isFunction(callback))
callback();
}
Apakah ini malas atau praktik yang buruk? Saya hanya bertanya karena ini menghasilkan lebih banyak fungsi yang membutuhkan logika yang sangat kecil.
programming-practices
coding-standards
Mark Brown
sumber
sumber
Assert.AreEqual<int>(expected, actual, message, arg1, arg2, arg3, ...);
. Yang kedua baik-baik saja. Saya berpotensi menyertakan bool flag opsional yang akan menentukan apakah akan membuang exception / etc. dalam kasus callback bukan suatu fungsi.def yes(): return 'yes'
Jawaban:
Hehe, oh Pak Brown, kalau saja saya bisa meyakinkan semua pengembang yang saya temui untuk menjaga fungsi mereka sekecil ini, percayalah, dunia perangkat lunak akan menjadi tempat yang lebih baik!
1) Pembacaan kode Anda meningkat sepuluh kali lipat.
2) Sangat mudah untuk mengetahui proses kode Anda karena mudah dibaca.
3) KERING - Jangan Ulangi Diri Anda - Anda menyesuaikan diri dengan ini dengan sangat baik!
4) Dapat diuji. Fungsi kecil sejuta kali lebih mudah untuk diuji daripada 200 metode garis yang kita lihat terlalu sering.
Oh dan jangan khawatir tentang "fungsi melompat" dalam hal kinerja. Build "release" dan optimisasi kompiler menangani hal ini untuk kami dengan sangat baik, dan kinerja 99% dari waktu di tempat lain dalam desain sistem.
Apakah ini malas? - Sangat kebalikannya!
Apakah ini praktik buruk? - Benar-benar tidak. Lebih baik menarik metode pembuatan metode ini daripada bola tar atau "Objek Dewa" yang oh terlalu umum.
Pertahankan kerja bagus sesama pengrajin;)
sumber
Saya akan mengatakan bahwa metode refactored terlalu pendek jika:
Ex:
atau...
Ex:
Ini bisa menjadi pola yang valid, tetapi saya hanya akan menguraikan metode configureDialog (), dalam contoh ini, kecuali saya bermaksud menimpanya atau menggunakan kembali kode ini di tempat lain.
sumber
Bisakah suatu fungsi terlalu pendek? Secara umum tidak.
Bahkan satu-satunya cara untuk memastikan bahwa:
Adalah untuk menjaga fungsi Anda sekecil mungkin. Atau, dengan kata lain, ekstrak fungsi dari fungsi Anda hingga Anda tidak dapat mengekstraksi lagi. Saya menyebutnya "Ekstrak sampai Anda jatuh."
Untuk menjelaskan ini: Fungsi adalah ruang lingkup dengan potongan fungsi yang berkomunikasi dengan variabel. Kelas juga merupakan ruang lingkup dengan potongan fungsi yang berkomunikasi dengan variabel. Jadi fungsi yang panjang selalu dapat digantikan oleh satu atau lebih kelas dengan metode kecil.
Juga, fungsi yang cukup besar untuk memungkinkan Anda mengekstrak fungsi lain darinya, sedang melakukan lebih dari satu hal menurut definisi . Jadi jika Anda dapat mengekstrak fungsi dari yang lain, Anda harus mengekstrak fungsi itu.
Beberapa orang khawatir bahwa ini akan mengarah pada proliferasi fungsi. Mereka benar. Itu akan. Sebenarnya itu hal yang baik. Itu bagus karena fungsi memiliki nama. Jika Anda berhati-hati dalam memilih nama yang baik, maka fungsi-fungsi ini bertindak sebagai tanda masuk yang mengarahkan orang lain melalui kode Anda. Memang, fungsi dengan nama baik di dalam kelas dengan nama baik di dalam ruang nama yang baik adalah salah satu cara terbaik untuk memastikan bahwa pembaca Anda TIDAK tersesat.
Ada lebih banyak tentang ini di Episode III dari Clean Code di cleancoders.com
sumber
Wow, sebagian besar jawaban ini sama sekali tidak membantu.
Tidak ada fungsi yang harus ditulis yang identitasnya adalah definisi . Yaitu, jika nama fungsi hanyalah blok kode fungsi yang ditulis dalam bahasa Inggris, maka jangan menuliskannya sebagai fungsi.
Pertimbangkan fungsi Anda
conditionMet
dan fungsi lainnya ini,addOne
(maafkan saya karena JavaScript saya yang berkarat):conditionMet
adalah definisi konseptual yang tepat;addOne
adalah tautologi .conditionMet
itu baik karena Anda tidak tahu apa yangconditionMet
diperlukan hanya dengan mengatakan "syarat bertemu", tetapi Anda dapat melihat mengapaaddOne
konyol jika Anda membacanya dalam bahasa Inggris:Demi cinta apa pun yang mungkin masih suci, tolong, jangan menulis fungsi tautologis!
(Dan untuk alasan yang sama, jangan menulis komentar untuk setiap baris kode !)
sumber
function nametoolong() { return name.size > 15; }
ataufunction successorIndex(x) { return x + 1; }
Jadi masalah dengan fungsi Anda sebenarnya hanya karena nama mereka buruk.Saya akan mengatakan bahwa jika Anda berpikir niat beberapa kode dapat ditingkatkan dengan menambahkan komentar, daripada menambahkan komentar itu, ekstrak kode ke dalam metode sendiri. Tidak peduli seberapa kecil kodenya.
Jadi misalnya jika kode Anda akan terlihat seperti:
buat itu terlihat seperti ini sebagai gantinya:
dengan
Atau dengan kata lain, ini bukan tentang panjang metode, tetapi tentang kode dokumentasi diri.
sumber
if x == PIXEL_ON
. Menggunakan konstanta bisa sama deskriptifnya dengan menggunakan metode, dan sedikit lebih singkat.Saya pikir inilah yang ingin Anda lakukan. Saat ini fungsi itu mungkin hanya satu atau dua baris tetapi seiring waktu ia dapat tumbuh. Juga memiliki lebih banyak panggilan fungsi memungkinkan Anda untuk membaca panggilan fungsi dan memahami apa yang terjadi di dalam sana. Ini membuat kode Anda sangat KERING (Jangan Ulangi Diri Sendiri) yang jauh lebih mudah dikelola.
sumber
conditionMet
itu nama yang terlalu umum, dan tidak perlu argumen, jadi ia menguji kondisi tertentu? (x == xCondition) dalam sebagian besar bahasa dan situasi sama ekspresifnya dengan 'xConditition'.Saya setuju dengan semua posting lain yang telah saya lihat. Ini gaya yang bagus.
Overhead metode sekecil itu mungkin nol karena pengoptimal dapat mengoptimalkan panggilan dan inline kode. Kode sederhana seperti ini memungkinkan pengoptimal untuk melakukan pekerjaan terbaiknya.
Kode harus ditulis untuk kejelasan dan kesederhanaan. Saya mencoba membatasi metode untuk salah satu dari dua peran: membuat keputusan; atau melakukan pekerjaan. Ini dapat menghasilkan satu metode garis. Semakin baik saya melakukan ini, semakin baik saya menemukan kode saya.
Kode seperti ini cenderung memiliki kohesi tinggi dan kopling rendah yang merupakan praktik pengkodean yang baik.
EDIT: Catatan tentang nama metode. Gunakan nama metode yang menunjukkan apa metode tidak bagaimana melakukannya. Saya menemukan verb_noun (_modifier) adalah skema penamaan yang baik. Ini memberi nama seperti Find_Customer_ByName daripada Select_Customer_Using_NameIdx. Kasus kedua cenderung menjadi salah ketika metode ini dimodifikasi. Dalam kasus pertama, Anda dapat menukar seluruh implementasi basis data Pelanggan.
sumber
Refactoring satu baris kode ke suatu fungsi tampaknya berlebihan. Mungkin ada kasus luar biasa, seperti ver loooooong / comples lines atau expessions, tapi saya tidak akan melakukan ini kecuali saya tahu fungsinya akan tumbuh di masa depan.
dan contoh pertama Anda mengisyaratkan penggunaan global (yang mungkin atau mungkin tidak berbicara tentang masalah lain dalam kode), saya akan refactor lebih lanjut, dan menjadikan kedua variabel sebagai parameter:
The
conditionMet
contoh mungkin berguna jika kondisi itu panjang dan berulang-ulang seperti:sumber
conditionMet
fungsi hanya verbose==
operator. Itu mungkin tidak berguna.conditionMet (x, relation condition) {
sini, di mana Anda melewatkan x, '==' dan relasi. Maka Anda tidak perlu mengulangi kode untuk '<', '>', '<=', '! =' Dan seterusnya. Di sisi lain - sebagian besar bahasa memiliki konstruksi ini sebagai operator (x == kondisi) melakukan hal itu. Fungsi untuk pernyataan atom adalah satu langkah terlalu jauh.Pertimbangkan ini:
Fungsi deteksi tabrakan sederhana:
Jika Anda menulis "liner" sederhana itu dalam kode Anda sepanjang waktu, Anda mungkin pada akhirnya akan membuat kesalahan. Plus, akan sangat menyiksa untuk menulis itu berulang-ulang.
sumber
#define
;)Tidak, dan itu jarang menjadi masalah. Sekarang jika seseorang merasa tidak ada fungsi yang harus lebih dari satu baris kode (jika hanya bisa sesederhana itu), itu akan menjadi masalah dan dalam beberapa hal malas karena mereka tidak memikirkan apa yang sesuai.
sumber
function isAdult () = { age >= 18; }
tapi pasti tidakisAtLeast18
.Saya akan mengatakan mereka terlalu pendek, tapi ini pendapat subjektif saya.
Karena:
Fungsi yang panjang buruk, tetapi fungsi yang lebih pendek dari 3 baris dan hanya melakukan 1 hal sama buruknya IMHO.
Jadi saya katakan hanya menulis fungsi kecil jika:
Saya yakin pengembang berikutnya (senior) akan memiliki hal-hal yang lebih baik untuk dilakukan daripada mengingat semua fungsi SetXToOne Anda. Jadi mereka akan berubah menjadi bobot mati segera.
sumber
Saya tidak suka contoh no. 1, karena nama generik ith.
conditionMet
tampaknya tidak generik, jadi itu singkatan dari kondisi tertentu? SukaIni akan baik-baik saja. Perbedaan semantik, sementara
tidak akan baik untuk saya.
Mungkin sering digunakan, dan dapat berubah kemudian:
juga baik-baik saja. Menggunakannya berkali-kali, Anda hanya perlu mengganti satu tempat, jika perlu - mungkin whipped cream bisa dilakukan besok.
bukan atom, dan harus memberi Anda kesempatan tes yang bagus.
Jika Anda harus melewati suatu fungsi, tentu saja, lewati apa pun yang Anda suka, dan tuliskan fungsi yang tampak konyol.
Tetapi secara umum, saya melihat lebih banyak fungsi, yang terlalu panjang, daripada fungsi yang terlalu pendek.
Kata terakhir: Beberapa fungsi hanya terlihat sesuai, karena mereka ditulis terlalu bertele-tele:
Jika Anda melihat, itu sama dengan
Anda tidak akan memiliki masalah dengan
dari pada
sumber
Tidak ada kode seperti tidak ada kode!
Tetap sederhana dan jangan terlalu rumit.
Itu tidak menjadi malas, itu melakukan pekerjaan Anda!
sumber
Ya, tidak masalah memiliki fungsi kode pendek. Dalam hal metode sebagai "getter", "setter", "accesors" sangat umum, seperti jawaban sebelumnya disebutkan.
Kadang-kadang, fungsi-fungsi pendek "aksesoris" itu virtual, karena ketika ditimpa dalam subclass fungsi akan memiliki lebih banyak kode.
Jika Anda ingin Anda berfungsi tidak begitu pendek, baik, dalam banyak fungsi, apakah global atau metode, saya biasanya menggunakan variabel "hasil" (gaya pascal) alih-alih pengembalian langsung, ini sangat membantu ketika menggunakan debugger.
sumber
Terlalu pendek tidak pernah menjadi masalah. Beberapa alasan untuk fungsi pendek adalah:
Dapat digunakan kembali
Misalnya jika Anda memiliki fungsi, seperti metode set, Anda mungkin menegaskannya untuk memastikan parameternya valid. Pemeriksaan ini harus dilakukan di mana pun variabel diatur.
Maintabilitas
Anda mungkin menggunakan beberapa pernyataan yang menurut Anda di masa depan dapat berubah. Misalnya Anda sekarang menunjukkan simbol dalam kolom, tetapi nanti itu mungkin berubah menjadi sesuatu yang lain (atau bahkan bunyi bip).
Keseragaman
Anda menggunakan misalnya pola fasad dan satu-satunya hal yang dilakukan suatu fungsi adalah meneruskan fungsi ke yang lain tanpa mengubah argumen.
sumber
Ketika Anda memberi nama bagian kode, itu pada dasarnya untuk memberinya nama . Ini bisa karena salah satu dari beberapa alasan, tetapi poin pentingnya adalah jika Anda dapat memberikannya nama yang bermakna yang menambah program Anda. Nama-nama seperti "addOneToCounter" tidak akan menambahkan apa pun, tetapi
conditionMet()
akan menambahkan .Jika Anda memerlukan aturan untuk mengetahui apakah cuplikan terlalu pendek atau terlalu panjang, maka pertimbangkan berapa lama Anda menemukan nama yang bermakna untuk cuplikan tersebut. Jika Anda tidak bisa dalam jumlah waktu yang wajar, maka potongannya tidak sesuai.
sumber
Tidak, tapi itu bisa terlalu singkat.
Ingat: Kode ditulis sekali, tetapi bacalah berkali-kali.
Jangan menulis kode untuk kompiler. Tulis untuk pengembang masa depan yang harus menjaga kode Anda.
sumber
Ya sayang, Fungsi bisa lebih kecil dan lebih kecil dan apakah itu baik atau buruk itu tergantung pada Bahasa / Kerangka yang Anda gunakan.
Menurut pendapat saya, saya sebagian besar bekerja pada Teknologi Front End, Fungsi Kecil sebagian besar digunakan sebagai fungsi pembantu Anda akan terikat untuk menggunakannya seperti banyak ketika bekerja dengan filter kecil dan menggunakan logika yang sama di seluruh aplikasi Anda. Jika aplikasi Anda memiliki terlalu banyak logika umum maka akan ada banyak fungsi kecil.
Tetapi dalam aplikasi di mana Anda tidak memiliki logika umum, Anda tidak akan terikat untuk membuat fungsi-fungsi kecil tetapi Anda dapat memecah kode Anda menjadi segmen-segmen di mana itu menjadi mudah bagi Anda untuk mengelola dan memahami.
Secara umum memecah kode besar Anda menjadi fungsi kecil adalah pendekatan yang sangat bagus. Dalam kerangka kerja dan bahasa modern Anda akan terikat untuk melakukannya misalnya
adalah fungsi anonim dalam ES 2017 JavaScript dan Typcript
dalam kode di atas Anda dapat melihat 3 Deklarasi fungsi dan 2 panggilan fungsi. Ini adalah Panggilan Layanan sederhana dalam Angular 4 dengan naskah. Anda dapat menganggapnya sebagai kebutuhan Anda
Di atas adalah 3 fungsi Anonim dalam Bahasa clojure
Yang di atas adalah deklarasi fungsional di clojure
Jadi ya FUNGSI bisa menjadi lebih kecil tetapi apakah itu baik atau buruk jika Anda memiliki fungsi seperti:
Yah itu bukan praktik yang baik untuk melakukannya tetapi bagaimana jika Anda menggunakan fungsi ini dalam tag HTML seperti yang kami lakukan dalam Kerangka Angular jika tidak ada dukungan untuk Peningkatan atau Penurunan dalam Templat HTML Sudut maka ini akan menjadi solusi untuk saya.
Mari kita ambil contoh lain
Contoh di atas adalah suatu keharusan ketika bermain ketika array di dalam Angular HTML Templates. Jadi terkadang Anda harus membuat fungsi kecil
sumber
Saya tidak setuju dengan jawaban yang hampir diberikan pada saat ini.
Baru-baru ini saya menemukan seorang kolega yang menulis semua anggota kelas seperti yang berikut:
Ini bisa menjadi kode yang baik dalam kasus sporadis, tetapi tentu tidak jika Anda mendefinisikan banyak kelas yang memiliki banyak properti. Saya tidak ingin mengatakan, dengan ini, bahwa metode seperti yang di atas tidak boleh ditulis. Tetapi, jika Anda akhirnya menulis sebagian besar kode sebagai "pembungkus" dari logika yang sebenarnya, ada sesuatu yang salah.
Mungkin programmer kehilangan logika keseluruhan, takut tentang perubahan di masa depan dan tentang refactoring kode.
Definisi antarmuka adalah karena kebutuhan nyata; memang jika Anda perlu mengatur dan mendapatkan properti sederhana (tanpa banyak logika, yang membuat anggota lebih pendek) itu mungkin. Tetapi, jika kebutuhan sebenarnya dapat dianalisis dengan cara yang berbeda, mengapa tidak mendefinisikan antarmuka yang lebih intuitif?
Untuk benar-benar menjawab pertanyaan, tentu saja tidak, dan alasannya sangat jelas: metode / properti / whatelse harus didefinisikan untuk apa yang dibutuhkannya. Bahkan fungsi virtual yang kosong memiliki alasan untuk tetap ada.
sumber