Bisakah suatu fungsi terlalu pendek?

125

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.

Mark Brown
sumber
3
Tidak, tidak terlalu pendek. Dalam C # saya akan melakukan 'kondisi bertemu' sebagai properti, yang elegan, dan akan mempertimbangkan untuk menggunakannya 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.
Pekerjaan
38
Ya, hanya dalam satu kasus: function myFunction () {}
Spooks
5
def yes(): return 'yes'
dietbuddha
3
@Spooks - Saya membagi rambut di sini tetapi fungsi kosong berlaku untuk setidaknya kelas adaptor misalnya MouseMotionAdapter di download.oracle.com/javase/6/docs/api/java/awt/event/… . Tentu saja ini hanya cara untuk mengatasi keterbatasan bahasa.
Aleksi Yrttiaho
3
@dietbuddha: Persyaratan baru saja berubah - sekarang harus mendukung dua bahasa untuk demo minggu depan. Orang yang menulis "def yes ()" merasa sangat senang dia sebelum mengubahnya menjadi "def yes (: (IsFrench ()? 'Oui': 'Ya')"
Andrew Shepherd

Jawaban:

167

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;)

Martin Blore
sumber
40
Anda tidak menjawab pertanyaan, Anda hanya memberitakan aturan yang aplikasi ekstremnya dipertanyakan di sini.
4
Jarang sekali saya menemukan keterbatasan hanya 1 yang membuat frustrasi. Namun, untuk jawaban ini, +1 tampaknya tidak adil.
Bevan
4
+5 ... oh hanya bisa memberi +1, oh well! Dan untuk mendukung MeshMan, saya menyarankan buku berikut oleh Robert C. Martin Clean code . Buku ini benar-benar mengubah cara saya memprogram.
Eric-Karl
10
Jawaban yang sangat disukai, tetapi saya tidak setuju dengan sebagian besar: 1) Fungsi yang sangat kecil menghasilkan lebih banyak kode secara keseluruhan, karena semua pipa diperlukan untuk setiap fungsi. Ini dapat mengurangi keterbacaan, terutama untuk proyek yang sangat besar. Juga, tergantung pada bahasa. 2) Tergantung sepenuhnya pada poin 1, dan karena itu tidak ada hubungannya dengan pertanyaan. 3) Apa? runCallback mengulangi "callback" empat kali, dan tiga kali merujuk pada variabel yang sama untuk menjalankan fungsi tunggal. 4) 200+ metode garis tentu saja tidak dapat diuji, tetapi ada jalan panjang dari itu menjadi satu baris.
l0b0
10
-1: Hal paling menakutkan di sini adalah jumlah suara yang diberikan untuk jawaban ini.
Luca
64

Saya akan mengatakan bahwa metode refactored terlalu pendek jika:

  • Ini menduplikasi operasi primitif, tanpa tujuan lain selain menjadikannya metode:

Ex:

boolean isNotValue() {
   return !isValue();
}

atau...

  • Kode hanya digunakan satu kali, dan maksudnya mudah dipahami sekilas.

Ex:

void showDialog() {
    Dialog singleUseDialog = new ModalDialog();
    configureDialog(singleUseDialog);
    singleUseDialog.show();
}

void configureDialog(Dialog singleUseDialog) {
    singleUseDialog.setDimensions(400, 300);
}

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.

RMorrisey
sumber
7
Memisahkan metode garis tunggal dalam kasus kedua dapat bermanfaat untuk menjaga tingkat abstraksi metode pemanggilan metode tetap. Contoh yang diberikan ada di pagar jika alasan ini digunakan: apakah lebar piksel tepat dan tinggi terlalu banyak detail untuk menampilkan dialog?
Aleksi Yrttiaho
2
Metode "isNotValue ()" diberi nama dengan buruk dan harus di refactored untuk memberi nama pertanyaan domain yang sebenarnya.
4
@Aleksi: Saya tidak setuju; detailnya sudah disembunyikan dalam metode showDialog () dalam contoh ini; tidak perlu melipatgandakannya. Contoh ini dimaksudkan untuk menunjukkan use case yang terisolasi; jika suatu pola diperlukan dengan konfigurasi dialog yang berbeda dalam kasus yang berbeda, masuk akal untuk kembali dan melakukan refactor setelah pola terbentuk.
RMorrisey
1
@ Torbjorn: Saya bisa melihat kasusnya, ketika Anda menjawab pertanyaan domain bisnis yang logikanya mungkin tidak jelas. Saya hanya menunjukkan bahwa ada beberapa kasus di mana itu berlebihan.
RMorrisey
3
Mungkin ini nitpicking, tetapi saya berpendapat bahwa dalam contoh Anda masalahnya bukan fungsi yang terlalu pendek, tetapi mereka tidak menambah nilai deskriptif.
keppla
59

Bisakah suatu fungsi terlalu pendek? Secara umum tidak.

Bahkan satu-satunya cara untuk memastikan bahwa:

  1. Anda telah menemukan semua kelas dalam desain Anda
  2. Fungsi Anda hanya melakukan satu hal.

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

Paman Bob.
sumber
5
Paman Bob! Senang bertemu Anda di sini. Seperti yang diharapkan, saran fantastis. Saya belum pernah mendengar istilah "Ekstrak sampai Anda jatuh" sebelumnya dan pasti akan menggunakan istilah ini di kantor pada hari Senin;).
Martin Blore
1
Apakah Anda bersedia menguraikan poin # 1 Anda? Menjelaskan bahwa dengan memberi contoh akan bagus.
Daniel Kaplan
53

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 conditionMetdan fungsi lainnya ini, addOne(maafkan saya karena JavaScript saya yang berkarat):

function conditionMet() { return x == condition; }

function addOne(x) { return x + 1; }

conditionMetadalah definisi konseptual yang tepat; addOneadalah tautologi . conditionMetitu baik karena Anda tidak tahu apa yang conditionMetdiperlukan hanya dengan mengatakan "syarat bertemu", tetapi Anda dapat melihat mengapa addOnekonyol jika Anda membacanya dalam bahasa Inggris:

"For the condition to be met is for x to equal condition" <-- explanatory! meaningful! useful!

"To add one to x is to take x and add one." <-- wtf!

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 !)

Rei Miyasaka
sumber
Beberapa konstruksi bahasa yang lebih kompleks mungkin tidak dikenal atau sulit dibaca, menjadikannya trik yang berguna.
3
Setuju, apa sebenarnya yang harus dibuat menjadi fungsi akan sangat tergantung pada bahasa yang sedang ditulis. Fungsi seperti addOne akan berguna jika Anda berada dalam bahasa seperti VHDL, di mana Anda benar-benar mendefinisikan arti menambahkan satu pada sebuah tingkat teori biner atau angka. Saya ingin berpikir bahwa tidak ada bahasa di luar sana yang begitu samar sehingga sulit dibaca bahkan untuk programmer yang dipraktekkan (mungkin brainf # ck), tetapi jika itu masalahnya, ide yang sama akan berlaku karena fungsi ini secara efektif merupakan terjemahan dari bahasa Inggris ke bahasa itu - jadi namanya tidak sama dengan definisi.
Rei Miyasaka
1
Saya berbicara tentang fungsi identitas hal-hal dari perpustakaan standar Haskell - Saya tidak berpikir Anda bisa mendapatkan lebih banyak "tautologis" maka itu :)
hugomg
1
@missingno Bah, itu curang: D
Rei Miyasaka
5
Jika Anda memberi nama fungsi berdasarkan tujuannya dan bukan berdasarkan isinya, mereka segera berhenti bersikap konyol. Jadi contoh Anda mungkin misalnya menjadi function nametoolong() { return name.size > 15; }atau function successorIndex(x) { return x + 1; } Jadi masalah dengan fungsi Anda sebenarnya hanya karena nama mereka buruk.
Hans-Peter Störr
14

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:

if x == 1 { ... } // is pixel on?

buat itu terlihat seperti ini sebagai gantinya:

if pixelOn() { ... }

dengan

function pixelOn() { return x == 1; }

Atau dengan kata lain, ini bukan tentang panjang metode, tetapi tentang kode dokumentasi diri.

Julio
sumber
5
Kolega saya yang terhormat menunjukkan bahwa Anda juga bisa menulis if x == PIXEL_ON. Menggunakan konstanta bisa sama deskriptifnya dengan menggunakan metode, dan sedikit lebih singkat.
Tom Anderson
7

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.

mpenrow
sumber
4
Jadi apa yang salah dengan memfaktorkannya nanti, ketika Anda bisa membuktikan bahwa Anda perlu, alih-alih sekarang, ketika itu baru saja mati?
dsimcha
Fungsi tidak tumbuh sendiri. IMHO contohnya buruk. conditionMetitu 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'.
pengguna tidak diketahui
Ya, dan itulah mengapa Anda ingin memiliki 75% + overhead dalam kode Anda? Singe liner yang ditulis sebagai 3 baris sebenarnya 300%.
Coder
5

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.

BillThor
sumber
+1 untuk menyebutkan inlining, merupakan pertimbangan utama dalam kinerja dan fungsi pendek.
Garet Claborn
4

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:

function conditionMet(x, condition){
   return x == condition;
}
....
conditionMet(1,(3-2));
conditionMet("abc","abc");

The conditionMetcontoh mungkin berguna jika kondisi itu panjang dan berulang-ulang seperti:

function conditionMet(x, someObject){
   return x == ((someObject.valA + someObject.valB - 15.4) / /*...whole bunch of other stuff...*/);
}
FrustratedWithFormsDesigner
sumber
1
Contoh pertamanya tidak mengisyaratkan global. Jika ada, itu adalah metode kohesif dalam kelas yang sangat kohesif di mana sebagian besar variabel pada objek.
Martin Blore
7
Itu conditionMetfungsi hanya verbose ==operator. Itu mungkin tidak berguna.
1
Saya jelas tidak menggunakan global. @MeshMan, di situlah contohnya berasal ... metode di kelas.
Mark Brown
1
@ Mark Brown: @ Markesh: Ok, saya kira contoh kode itu terlalu samar untuk diketahui ...
FrustratedWithFormsDesigner
Saya mencium bau di 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.
pengguna tidak diketahui
3

Pertimbangkan ini:

Fungsi deteksi tabrakan sederhana:

bool collide(OBJ a, OBJ b)
{
    return(pow(a.x - b.x, 2) + pow(a.y - b.y, 2) <= pow(a.radius + b.radius, 2));
}

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.

muntoo
sumber
Jika kita berurusan dengan C di sini, kita bisa saja menyalahgunakan #define;)
Cole Johnson
Anda bahkan mungkin ingin menukar ini untuk hipot yang lebih lambat namun tahan- luapan jika ukuran atau jarak Anda menjadi sangat besar. Ini jelas jauh lebih mudah dilakukan sekali.
Matt Krause
2

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.

JeffO
sumber
Saya tidak akan menghitungnya dalam baris kode, tetapi dalam ekspresi. "(x == kondisi)" adalah atom, jadi saya akan memasukkannya ke dalam metode / fungsi saja, jika digunakan beberapa kali DAN mungkin dapat diubah, seperti function isAdult () = { age >= 18; }tapi pasti tidak isAtLeast18.
pengguna tidak diketahui
2

Saya akan mengatakan mereka terlalu pendek, tapi ini pendapat subjektif saya.

Karena:

  • Tidak ada alasan untuk membuat fungsi jika hanya digunakan sekali atau dua kali. Melompat ke def menghisap. Terutama dengan kode VS dan C ++ yang luar biasa cepat.
  • Ikhtisar kelas. Ketika Anda memiliki ribuan fungsi kecil, itu membuat saya marah. Saya menikmati ketika saya dapat melihat definisi kelas dan dengan cepat melihat apa yang dilakukannya, bukan bagaimana itu SetXToOne, SetYToVector3, MultiplyNumber, + 100 setter / getter.
  • Dalam sebagian besar proyek, pembantu ini menjadi sangat berat setelah satu kali dua fase refactoring, dan kemudian Anda melakukan "cari semua" -> hapus untuk menghilangkan kode usang, biasanya ~ 25% + darinya.

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:

  • 3+ baris kode
  • Apakah hal-hal yang mungkin terlewatkan oleh devs junior (tidak tahu)
  • Apakah validasi tambahan
  • Digunakan, atau akan digunakan minimal 3x
  • Menyederhanakan antarmuka yang sering digunakan
  • Tidak akan menjadi beban mati selama refactoring berikutnya
  • Memiliki beberapa makna khusus, misalnya spesialisasi template atau sesuatu
  • Apakah beberapa pekerjaan isolasi - referensi const, mempengaruhi parameter bisa berubah, apakah pengambilan anggota pribadi

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.

Coder
sumber
1

Saya tidak suka contoh no. 1, karena nama generik ith.

conditionMettampaknya tidak generik, jadi itu singkatan dari kondisi tertentu? Suka

isAdult () = { 
  age >= 18 
}

Ini akan baik-baik saja. Perbedaan semantik, sementara

isAtLeast18 () { age >= 18; } 

tidak akan baik untuk saya.

Mungkin sering digunakan, dan dapat berubah kemudian:

getPreferredIcecream () { return List ("banana", "choclate", "vanilla", "walnut") }

juga baik-baik saja. Menggunakannya berkali-kali, Anda hanya perlu mengganti satu tempat, jika perlu - mungkin whipped cream bisa dilakukan besok.

isXYZ (Foo foo) { foo.x > 15 && foo.y < foo.x * 2 }

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:

function lessThan (a, b) {
  if (a < b) return true else return false; 
}

Jika Anda melihat, itu sama dengan

return (a < b); 

Anda tidak akan memiliki masalah dengan

localLessThan = (a < b); 

dari pada

localLessThan = lessThan (a, b); 
Pengguna tidak diketahui
sumber
0

Tidak ada kode seperti tidak ada kode!

Tetap sederhana dan jangan terlalu rumit.

Itu tidak menjadi malas, itu melakukan pekerjaan Anda!

RDL
sumber
0

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.

function int CalculateSomething() {
  int Result = -1;

   // more code, maybe, maybe not

  return Result;
}
umlcat
sumber
0

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.

Michel Keijzers
sumber
0

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.

pengguna1249
sumber
0

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.

Jim G.
sumber
-1

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

data => initScroll(data)

adalah fungsi anonim dalam ES 2017 JavaScript dan Typcript

getMarketSegments() {
 this.marketService.getAllSegments(this.project.id)
  .subscribe(data => this.segments = data, error => console.log(error.toString()));
}

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

([] 0)
([x] 1)
([x y] 2)

Di atas adalah 3 fungsi Anonim dalam Bahasa clojure

(def hello (fn [] "Hello world"))

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:

incrementNumber(numb) { return ++numb; }

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

insertInArray(array, newKey) {
 if (!array.includes(newKey)) {
   array.push(newKey);
 }
}

Contoh di atas adalah suatu keharusan ketika bermain ketika array di dalam Angular HTML Templates. Jadi terkadang Anda harus membuat fungsi kecil

Anwaar Ulhaq
sumber
-2

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:

 void setProperty(int value){ mValue=value; }
 int getProperty() const { return (mValue); }

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.

Luca
sumber
6
Ada alasan bagus untuk menambahkan metode accessor / mutator, yang Anda beri petunjuk di bawah "takut tentang masa depan ... refactoring". Tetapi Anda juga benar bahwa itu tidak menambah nilai pada kode. Baik dengan mengurangi ukuran (lokal atau global) atau meningkatkan keterbacaan. Dalam pikiran saya, ini berbicara tentang desain bahasa yang buruk di Jawa dan konvensi JavaBeans. Ini adalah salah satu area (dari banyak) di mana C # berhasil meningkatkan bahasa untuk mengatasi kedua masalah dengan sintaksis properti otomatis . Sebagai seorang programmer Java, saya setuju dengan gaya mentah Anda untuk kelas struct-like dasar.
Anm
1
Fungsi getter / setter baik meskipun semua yang mereka lakukan sekarang adalah membaca atau menulis variabel. Secara praktis, Anda bisa membayangkan skenario di mana nanti Anda memutuskan untuk mencetak nilai ke layar setiap kali bidang berubah, atau untuk memeriksa apakah nilai itu valid atau tidak. (Mungkin itu adalah penyebut untuk pecahan, dan Anda ingin memeriksa untuk memastikan itu bukan nol.)
Rei Miyasaka
2
getter dan setter mengerikan, penggunaannya valid meskipun demikian. Jika perlu menggunakannya, saya menganggapnya sebagai kegagalan bahasa.
Carson Myers
@ Reei: mengapa kelas eksternal perlu memeriksa nilai penyebutnya? Itu harus dilakukan oleh fungsi divide () dari kelas Fraction atau kelas Fraction harus menyediakan isDivisible () untuk memeriksa penyebut nol. Yang memerlukan getter / setter biasanya adalah bau kode yang kelas Anda memiliki kopling tinggi dan / atau kohesi rendah (yaitu buruk).
Lie Ryan
@ Lie What? Saya tidak pernah mengatakan kelas eksternal harus digunakan untuk memeriksa penyebut. Saya mengatakan bahwa kelas eksternal mungkin menetapkan penyebut ke 0 secara tidak sengaja. Tujuan terjadinya pemeriksaan validitas di setter adalah untuk mendorong bug dalam kode konsumen ditemukan lebih awal. Menyediakan fungsi isDivisible () yang mungkin atau mungkin tidak dipanggil juga tidak berfungsi untuk itu. Dan bagaimana tepatnya getter / setter yang membutuhkan mengindikasikan bahwa ada kopling tinggi?
Rei Miyasaka