Saya mengerti pentingnya kode yang terdokumentasi dengan baik. Tetapi saya juga memahami pentingnya kode dokumentasi diri . Semakin mudah membaca fungsi tertentu secara visual, semakin cepat kita dapat melanjutkan selama pemeliharaan perangkat lunak.
Dengan itu, saya suka memisahkan fungsi besar menjadi yang lebih kecil. 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.
[Sunting]
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.
[Sunting]
Di bawah ini, saya menyertakan dua versi tentang bagaimana saya bisa menyelesaikan masalah saya. Yang pertama menyelesaikannya dengan tidak memisahkan potongan kode besar. Yang kedua melakukan hal-hal yang terpisah.
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?
Jawaban:
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 sampai ke
startTheEngine()
metode dalam kode Anda, dapat mengabaikan semua rincian tingkat yang lebih rendah sepertiopenIgnitionModule()
,turnDistributorMotor()
,sendSparksToSparkPlugs()
,injectFuelIntoCylinders()
,activateStarterSolenoid()
, dan semua lainnya yang kompleks, kecil, fungsi yang harus dijalankan untuk memfasilitasi fungsi yang jauh lebih besar, lebih abstrakstartTheEngine()
.Kecuali jika masalah yang Anda hadapi dalam kode Anda berhubungan langsung dengan salah satu komponen itu, pengelola kode dapat melanjutkan, mengabaikan fungsi kotak pasir yang dienkapsulasi.
Ini juga memiliki keuntungan tambahan untuk membuat kode Anda lebih mudah diuji. . Sebagai contoh, saya dapat menulis test case untuk
turnAlternatorMotor(int revolutionRate)
dan menguji fungsionalitasnya 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 saja daripada 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.
sumber
myString.replaceAll(pattern, originalData);
atau saya menyisipkan seluruh metode replaceAll dalam kode saya, termasuk array char backing yang mewakili objek string yang mendasari setiap dan setiap kali saya perlu menggunakan fungsionalitas String?Iya dan tidak. Prinsip dasarnya adalah: suatu metode harus melakukan satu hal dan satu hal saja
Benar untuk "memecah" metode Anda menjadi metode yang lebih kecil. Kemudian lagi, metode-metode itu seharusnya cukup umum untuk tidak hanya melayani metode "besar" itu 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 gunakan injeksi dependensi
sumber
Saya pikir secara umum lebih baik berbuat salah pada fungsi yang terlalu banyak daripada terlalu sedikit. Dua pengecualian untuk aturan yang saya lihat dalam praktik adalah untuk prinsip KERING dan YAGNI . 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 "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.
sumber
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 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.
Apa yang mungkin Anda miliki adalah kelas baru dengan antarmuka publiknya sendiri yang lebih fokus dan 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.
sumber
Hampir setiap proyek OO yang pernah saya ikuti menderita karena kelas yang terlalu besar, dan metode yang terlalu lama.
Ketika saya merasakan perlunya komentar yang menjelaskan bagian kode selanjutnya, 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 kecil itu.
sumber
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-metode pribadi 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 hanya potongan cerita panjang yang dibagi secara sewenang-wenang, masing-masing menjadi tidak berarti di luar konteks keseluruhan.
sumber
Kutipan dari Clean Code R. Martin (p. 176):
sumber
Beberapa opsi:
Tidak apa-apa. Cukup beri nama metode pribadi dan beri nama metode publik Anda. Dan sebutkan metode publik Anda dengan baik.
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.
sumber
Saya tidak berpikir ada masalah "terlalu banyak metode pribadi" jika rasanya seperti itu mungkin merupakan gejala arsitektur kode yang buruk.
Inilah yang saya pikirkan tentang hal itu ... Jika arsitekturnya dirancang dengan baik, umumnya 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.
sumber
Iya.
Dalam Python konsep "pribadi" (seperti yang digunakan oleh C ++, Java dan C #) tidak benar-benar ada.
Ada konvensi penamaan "semacam pribadi", tetapi 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.
sumber