it-swarm-id.com

Adakah hal yang memiliki terlalu banyak fungsi / metode pribadi?

Saya mengerti pentingnya kode yang terdokumentasi dengan baik. Tetapi saya juga memahami pentingnya kode yang dapat didokumentasikan sendiri . Semakin mudah membaca fungsi tertentu secara visual, semakin cepat kita dapat melanjutkan selama pemeliharaan perangkat lunak.

Dengan itu, saya ingin memisahkan fungsi besar menjadi yang lebih kecil lainnya. Tapi saya melakukannya ke titik di mana kelas dapat memiliki lebih dari lima dari mereka hanya untuk melayani satu metode publik. Sekarang gandakan lima metode pribadi dengan lima metode publik, dan Anda mendapatkan sekitar dua puluh lima metode tersembunyi yang mungkin akan dipanggil hanya satu kali oleh metode publik tersebut.

Tentu, sekarang lebih mudah untuk membaca metode-metode publik itu, tetapi saya tidak bisa tidak berpikir bahwa memiliki terlalu banyak fungsi adalah praktik yang buruk.

[Edit]

Orang-orang bertanya kepada saya mengapa saya pikir memiliki terlalu banyak fungsi adalah praktik yang buruk.

Jawaban sederhana: itu adalah firasat.

Kepercayaan saya, sedikit pun, tidak didukung oleh pengalaman rekayasa perangkat lunak selama berjam-jam. Hanya ketidakpastian yang memberi saya "blok penulis", tetapi untuk seorang programmer.

Di masa lalu, saya hanya memprogram proyek pribadi. Baru-baru ini saya pindah ke proyek berbasis tim. Sekarang, saya ingin memastikan bahwa orang lain dapat membaca dan memahami kode saya.

Saya tidak yakin apa yang akan meningkatkan keterbacaan. Di satu sisi, saya berpikir untuk memisahkan satu fungsi besar menjadi yang lebih kecil dengan nama yang dapat dipahami. Tetapi ada sisi lain dari diri saya yang mengatakan bahwa itu hanya mubazir.

Jadi, saya meminta ini untuk menerangi diri saya sendiri untuk memilih jalan yang benar.

[Edit]

Di bawah, saya menyertakan dua versi tentang bagaimana saya dapat menyelesaikan masalah saya. Yang pertama menyelesaikannya dengan tidak memisahkan potongan kode yang besar. Yang kedua tidak memisahkan hal-hal.

Versi pertama:

public static int Main()
{
    // Displays the menu.
    Console.WriteLine("Pick your option");
    Console.Writeline("[1] Input and display a polynomial");
    Console.WriteLine("[2] Add two polynomials");
    Console.WriteLine("[3] Subtract two polynomials");
    Console.WriteLine("[4] Differentiate two polynomials");
    Console.WriteLine("[0] Quit");
}

Versi kedua:

public static int Main()
{
    DisplayMenu();
}

private static void DisplayMenu()
{
    Console.WriteLine("Pick your option");
    Console.Writeline("[1] Input and display a polynomial");
    Console.WriteLine("[2] Add two polynomials");
    Console.WriteLine("[3] Subtract two polynomials");
    Console.WriteLine("[4] Differentiate two polynomials");
    Console.WriteLine("[0] Quit");
}

Dalam contoh di atas, yang terakhir memanggil fungsi yang hanya akan digunakan sekali selama seluruh runtime program.

Catatan: kode di atas digeneralisasi, tetapi sifatnya sama dengan masalah saya.

Sekarang, inilah pertanyaan saya: yang mana? Apakah saya memilih yang pertama, atau yang kedua?

63
Sal

Sekarang gandakan lima metode pribadi dengan lima metode publik, dan Anda mendapatkan sekitar dua puluh lima metode tersembunyi yang mungkin akan dipanggil hanya satu kali oleh metode publik tersebut.

Inilah yang dikenal sebagai Enkapsulasi , yang menciptakan Abstraksi Kontrol di tingkat yang lebih tinggi. Ini hal yang baik.

Ini berarti bahwa siapa pun yang membaca kode Anda, ketika mereka mendapatkan metode startTheEngine() dalam kode Anda, dapat mengabaikan semua detail level yang lebih rendah seperti openIgnitionModule(), turnDistributorMotor() , sendSparksToSparkPlugs(), injectFuelIntoCylinders(), activateStarterSolenoid(), dan semua fungsi kompleks, kecil, lainnya yang harus dijalankan untuk memfasilitasi fungsi yang jauh lebih besar, lebih abstrak dari startTheEngine().

Kecuali jika masalah yang Anda hadapi dalam kode Anda berhubungan langsung dengan salah satu komponen itu, pengelola kode dapat melanjutkan, mengabaikan fungsionalitas kotak pasir yang dienkapsulasi.

Ini juga memiliki keuntungan tambahan membuat kode Anda lebih mudah untuk diuji. . Sebagai contoh, saya dapat menulis sebuah test case untuk turnAlternatorMotor(int revolutionRate) dan menguji fungsionalitasnya yang sepenuhnya independen dari sistem lain. Jika ada masalah dengan fungsi itu dan outputnya tidak seperti yang saya harapkan, maka saya tahu apa masalahnya.

Kode yang tidak dipecah menjadi komponen-komponen jauh lebih sulit untuk diuji. Tiba-tiba, pengelola Anda hanya melihat abstraksi yang ada dan tidak bisa menggali ke dalam komponen yang terukur.

Saran saya adalah tetap melakukan apa yang Anda lakukan karena skala kode Anda, mudah dipelihara, dan dapat digunakan dan diperbarui untuk tahun-tahun mendatang.

36
jmort253

Iya dan tidak. Prinsip dasarnya adalah: sebuah metode harus melakukan satu hal dan satu hal saja

Benar untuk "memecah" metode Anda menjadi metode yang lebih kecil. Kemudian lagi, metode-metode tersebut seharusnya cukup umum untuk tidak saja melayani metode "besar" tetapi dapat digunakan kembali di tempat lain. Dalam beberapa kasus suatu metode akan mengikuti struktur pohon sederhana, seperti Metode Inisialisasi yang memanggil InitializePlugins, InitializeInterface dll.

Jika Anda memiliki metode/kelas yang sangat besar itu biasanya merupakan pertanda bahwa ia melakukan banyak hal dan Anda perlu melakukan beberapa refactoring untuk memecah "gumpalan". Perphaps menyembunyikan beberapa kompleksitas di kelas lain di bawah abstraksi, dan memang menggunakan injeksi dependensi

22
Homde

Saya pikir secara umum lebih baik berbuat salah di samping terlalu banyak fungsi daripada terlalu sedikit. Dua pengecualian untuk aturan yang saya lihat dalam praktek adalah untuk DRY dan YAGNI = = prinsip. Jika Anda memiliki banyak fungsi yang hampir identik, Anda harus menggabungkannya dan menggunakan parameter untuk menghindari pengulangan. Anda juga dapat memiliki terlalu banyak fungsi jika Anda membuatnya "untuk berjaga-jaga" dan tidak digunakan. Saya sama sekali tidak melihat ada yang salah dengan memiliki fungsi yang hanya digunakan sekali jika menambah keterbacaan dan pemeliharaan.

17
Karl Bielefeldt

jawaban jmort253 yang bagus mengilhami saya untuk menindaklanjuti dengan jawaban "ya, tapi" ...

Memiliki banyak metode pribadi kecil bukanlah hal yang buruk, tetapi perhatikan perasaan picik yang membuat Anda memposting pertanyaan di sini :). Jika Anda sampai pada titik di mana Anda sedang menulis tes yang difokuskan hanya pada metode pribadi (baik dengan memanggil mereka secara langsung, atau dengan membuat skenario sehingga seseorang dipanggil dengan cara tertentu supaya Anda dapat menguji hasilnya) maka Anda harus mengambil langkah mundur.

Yang mungkin Anda miliki adalah kelas baru dengan antarmuka publiknya sendiri yang lebih terfokus, berusaha melarikan diri. Pada titik itu Anda mungkin ingin berpikir tentang mengekstraksi kelas untuk merangkum bagian dari fungsionalitas kelas yang ada yang saat ini hidup dalam metode pribadi. Sekarang kelas asli Anda dapat menggunakan kelas baru Anda sebagai dependensi, dan Anda dapat menulis lebih banyak tes terfokus terhadap kelas itu secara langsung.

10
Pete Hodgson

Hampir setiap OO proyek yang pernah saya ikuti menderita dengan buruk dari kelas yang terlalu besar, dan metode yang terlalu lama.

Ketika saya merasakan perlunya komentar yang menjelaskan bagian kode berikutnya, maka saya mengekstrak bagian itu menjadi metode yang terpisah. Dalam jangka panjang, ini membuat kode lebih pendek. Metode-metode kecil itu dapat digunakan kembali lebih dari yang Anda harapkan pada awalnya. Anda mulai melihat peluang untuk mengumpulkan banyak dari mereka ke dalam kelas yang terpisah. Segera Anda memikirkan masalah Anda di tingkat yang lebih tinggi, dan seluruh upaya berjalan jauh lebih cepat. Fitur-fitur baru lebih mudah untuk ditulis, karena Anda dapat membangun kelas-kelas kecil yang Anda buat dari metode-metode kecil itu.

8
kevin cline

Kelas dengan 5 metode publik dan 25 metode pribadi sepertinya tidak terlalu besar bagi saya. Pastikan kelas Anda memiliki tanggung jawab yang jelas dan jangan terlalu khawatir tentang jumlah metode.

Yang mengatakan, metode pribadi itu harus fokus pada satu aspek spesifik dari seluruh tugas, tetapi tidak dalam cara "doSomethingPart1", "doSomethingPart2". Anda tidak akan memperoleh apa-apa jika metode pribadi itu hanyalah potongan-potongan cerita panjang yang dibagi secara sewenang-wenang, masing-masing menjadi tidak berarti di luar konteks keseluruhan.

7
user281377

Kutipan dari R. Martin Clean Code (hlm. 176):

Bahkan konsep yang mendasar seperti penghapusan duplikasi, ekspresi kode, dan SRP dapat diambil terlalu jauh. Dalam upaya membuat kelas dan metode kita kecil, kita mungkin membuat terlalu banyak kelas dan metode kecil. Jadi aturan ini [meminimalkan jumlah kelas dan metode] menyarankan agar kita juga menjaga agar fungsi dan kelas kita tetap rendah. Hitungan kelas dan metode yang tinggi kadang-kadang merupakan hasil dari dogmatisme sia-sia.

4
user2418306

Beberapa opsi:

  1. Tidak apa-apa. Cukup beri nama metode pribadi dan beri nama metode publik Anda. Dan sebutkan metode publik Anda dengan baik.

  2. Abstraksi beberapa metode penolong ini ke dalam kelas penolong atau modul penolong. Dan pastikan kelas/modul penolong ini dinamai dengan baik dan merupakan abstraksi yang solid di dalam dan dari diri mereka sendiri.

3
yfeldblum

Saya pikir tidak pernah ada masalah "terlalu banyak metode pribadi" jika dirasa seperti itu mungkin merupakan gejala dari arsitektur kode yang buruk.

Ini adalah bagaimana saya memikirkannya ... Jika arsitektur dirancang dengan baik, secara umum jelas di mana kode yang melakukan X seharusnya. Dapat diterima jika ada beberapa pengecualian untuk ini - tetapi ini harus benar-benar luar biasa jika tidak refactor arsitektur untuk menangani ini sebagai standar.

Jika masalahnya adalah saat membuka kelas Anda, itu penuh dengan metode pribadi yang memecah potongan yang lebih besar menjadi potongan kode yang lebih kecil, maka mungkin ini adalah gejala arsitektur yang hilang. Alih-alih kelas dan arsitektur, area kode ini telah diimplementasikan secara prosedural dalam satu kelas.

Menemukan keseimbangan di sini tergantung pada proyek dan persyaratannya. Argumen kontra untuk ini adalah mengatakan bahwa seorang programmer junior dapat mengetuk solusi dalam 50 baris kode yang mengambil arsitek 50 kelas.

1
Michael Shaw

Adakah hal yang memiliki terlalu banyak fungsi/metode pribadi?

Iya.

Dalam Python konsep "pribadi" (seperti yang digunakan oleh C++, Java dan C #) tidak benar-benar ada.

Ada konvensi penamaan "semacam pribadi", tapi hanya itu.

Pribadi dapat menyebabkan kode sulit diuji. Itu juga dapat mematahkan "Prinsip Terbuka-Tertutup" dengan membuat kode hanya ditutup.

Akibatnya, untuk orang-orang yang telah menggunakan Python, fungsi pribadi tidak memiliki nilai. Jadikan semuanya publik dan dilakukan dengan itu.

0
S.Lott