Dinamakan argumen (parameter) sebagai alat bantu keterbacaan

11

Beberapa waktu yang lalu saya banyak memprogram dalam ADA, dan itu normal untuk menyebutkan argumen ketika menjalankan fungsi - SomeObject.DoSomething (SomeParameterName => someValue);

Sekarang C # mendukung argumen bernama, saya berpikir untuk kembali ke kebiasaan ini dalam situasi di mana mungkin tidak jelas apa arti argumen.

Anda mungkin berpendapat bahwa itu harus selalu jelas apa artinya argumen, tetapi jika Anda memiliki argumen boolean, dan penelepon menyampaikan "benar" atau "salah" maka kualifikasi nilai dengan nama membuat situs panggilan lebih mudah dibaca.

contentFetcher.DownloadNote (catatan, manual: true);

Saya kira saya bisa membuat Enums daripada menggunakan benar atau salah (Manual, Otomatis dalam kasus ini).

Apa yang Anda pikirkan sesekali menggunakan argumen bernama untuk membuat kode lebih mudah dibaca?

Damian
sumber
Komentar parameter di atas metode juga membantu.
Amir Rezaei
1
@ amir-rezaei: Komentar parameter di atas metode hanya membantu jika Anda dapat mempercayai komentar. Kecuali jika Anda memiliki pengembang yang baik dan proses peninjauan kode yang baik, saya tidak akan mempercayai komentarnya.
btilly
Sebagai pengguna Ada satu kali sendiri, saya untuk penggunaan sesekali seperti yang Anda jelaskan. Begitulah cara saya mengingat mereka digunakan di Ada, BTW - Saya tidak akan menyebutnya "abnormal", tetapi kata "normal" tampaknya menyiratkan sebagian besar panggilan akan menentukan nama parameter, yang bukan bagaimana saya mengingat sesuatu. Tentu saja konvensi berbeda-beda, tetapi kekacauan yang tidak perlu adalah konvensi yang buruk dalam bahasa apa pun.
Steve314
Saya setuju penggunaan Anda di Ada - itu bukan sesuatu yang kami lakukan sepanjang waktu, tetapi membantu.
Damian

Jawaban:

7

Ini disarankan dalam pengembangan C ++, dan Stroustrup membahasnya dalam "Desain dan Evolusi C ++", halaman 153 dan selanjutnya. Proposal ini dibentuk dengan baik, dan mengacu pada pengalaman sebelumnya dengan Ada. Itu tidak diadopsi.

Alasan terbesar adalah bahwa tidak ada yang ingin mendorong fungsi dengan sejumlah besar parameter. Setiap fitur tambahan dalam bahasa memerlukan biaya, dan tidak ada keinginan untuk menambahkan fitur untuk membuatnya lebih mudah untuk menulis program yang buruk.

Itu juga menimbulkan pertanyaan tentang apa nama parameter kanonik itu, khususnya dalam header file kode konvensional. Beberapa organisasi memiliki nama parameter yang lebih panjang dan lebih deskriptif dalam file .h, dan lebih pendek dan lebih mudah untuk mengetik nama dalam file .cpp (ganti akhiran file yang diinginkan). Membutuhkan hal yang sama akan menjadi biaya tambahan pada kompilasi, dan menggabungkan nama-nama di antara file sumber dapat menyebabkan bug halus.

Itu juga dapat ditangani dengan menggunakan objek daripada panggilan fungsi. Alih-alih panggilan GetWindow dengan selusin parameter, buat kelas Window dengan selusin variabel pribadi, dan tambahkan setter yang diperlukan. Dengan merantai setter, mungkin untuk menulis sesuatu seperti my_window.SetColor(green).SetBorder(true).SetBorderSize(3);. Mungkin juga memiliki fungsi yang berbeda dengan standar berbeda yang memanggil fungsi yang benar-benar berfungsi.

Jika Anda hanya khawatir tentang efek dokumentasi contentFetcher.DownloadNote(note, manual : true);, Anda selalu dapat menulis sesuatu seperti contentFetcher.DownloadNote(note, /* manual */ true);, jadi itu bahkan tidak sangat membantu dalam dokumentasi.

David Thornley
sumber
Lucunya ketika saya pindah dari Ada ke C, saya mulai menggunakan konvensi yang Anda jelaskan - meskipun kode pengulas membencinya. Setuju untuk tidak menggunakannya untuk sejumlah besar parameter.
Damian
7

Saya pikir ini masalah membuat kode buruk lebih mudah dibaca, daripada "praktik terbaik".

Memiliki metode (atau kontraktor) yang mengambil 20 parameter adalah "bau buruk" dan kemungkinan disebabkan oleh masalah dalam desain Anda. Namun jika saya terpaksa bekerja pada kode ketika metode mengambil banyak parameter, maka parameter bernama membuat kode kurang sulit untuk dipahami.

Ketika metode hanya memiliki 1 atau 2 parameter dan jelas dari nama metode apa parameternya, kemudian bernama parameter tidak menambahkan apa pun. Ini adalah kasus ideal untuk masuk

Jika semua kode yang Anda kerjakan ditulis sebagai par pada buku " kode bersih ", maka Anda akan menggunakan sangat sedikit untuk parameter bernama, namun kita hidup di dunia nyata.

Ian
sumber
1
Suatu fungsi dengan dua parameter bisa membingungkan, jika kedua parameternya bertipe sama dan tanpa petunjuk yang mana. Tentu saja Anda dapat memberi nama fungsi dengan cara yang memberikan petunjuk itu, tetapi Anda benar-benar hanya melakukan apa yang dilakukan oleh nama parameter - kecuali bahwa Anda membuatnya wajib untuk memasukkan verbositas itu bahkan ketika konteksnya (misalnya ekspresi yang memasok parameter) memperjelas parameter yang mana.
Steve314
1
@ Steve314 Contoh:void TrackDataChange(Data oldData, Data newData)
Alexander
3

Saya setuju bahwa menambahkan nama parameter membuatnya lebih mudah dibaca. Namun, sebagian besar buku yang saya baca tampaknya menganggap beralih boolean sebagai praktik yang buruk. Saya terkadang melakukan ini:

public Content DownloadNote(Note note)
{
    return downloadNote(note, manual: false);
}

public Content DownloadNoteManually(Note note)
{
    return downloadNote(note, manual: true);
}

Itu memang memberi Anda lebih banyak fleksibilitas saat menerapkan API Anda. Ini juga memungkinkan Anda untuk mengontrol case di mana Anda memiliki beberapa switch boolean, tetapi tidak semuanya aktif pada saat yang sama.

Scott Whitlock
sumber
3
Jika Anda memiliki x pilihan, apakah Anda akan membuat 2 ^ x frontend?
apoorv020
@ apoorv020 - jika saya memiliki cukup parameter untuk pemanggilan metode yang 2 ^ x menjadi signifikan, saya akan membuat kelas baru untuk menampung nilai parameter, dan hanya meneruskan satu parameter.
Scott Whitlock
@ scott-whitlock: Opsi 1 - buat objek, atur properti x, panggil metode sekali dengan objek Anda. Opsi 2 - memanggil metode dengan parameter x bernama. Mana yang lebih baik tergantung pada bahasa Anda. Dalam bahasa yang diketik secara dinamis, opsi 1 membutuhkan pelat ketel yang jauh lebih besar tanpa penguatan, dan karenanya lebih buruk. Dalam bahasa yang diketik secara statis Anda masih menambahkan boilerplate, tetapi tes untuk kunci yang salah nama bisa dilakukan pada waktu kompilasi daripada waktu berjalan. Oleh karena itu opsi 1 lebih baik di C #, tetapi opsi 2 adalah kemenangan yang jelas dalam Python.
btilly
@ btilly - seperti yang ditunjukkan Ian, Clean Code dengan jelas memberi tahu Anda untuk tidak memiliki fungsi dengan lebih dari 2 atau 3 parameter. Agar adil, itu berurusan dengan Java, yang diketik secara statis. OP juga bertanya tentang C #, yang diketik secara statis. Saya masih lebih suka menggunakan kelebihan fungsi dan / atau nama fungsi yang berbeda persis bernama dari daftar panjang parameter.
Scott Whitlock
@ scott-whitlock: Apakah kita sebenarnya tidak setuju? Kami sepakat tentang apa yang terbaik di C #. Kita berdua tahu apa yang dikatakan Clean Code. Maksud saya adalah bahwa penting untuk memahami mengapa itu baik, sehingga Anda tahu kapan saran itu cocok atau tidak cocok dengan lingkungan yang berbeda.
btilly
3

Saya sangat percaya pada parameter bernama dalam situasi di mana jenis dan semantik tidak jelas dari nama metode. Pengalaman saya adalah bahwa beberapa orang membaca dokumentasi.

Yang sedang dikatakan, parameter bernama tidak boleh menjadi alternatif untuk membuat daftar argumen yang masuk akal, menggunakan objek pembantu (untuk "mengikat" bersama argumen terkait semantik), dan menggunakan enumerasi jika relevan.

Uri
sumber
0

Saya pikir ini lebih berguna dalam bahasa non-OO, di mana Anda mungkin memiliki satu fungsi yang harus melakukan sesuatu dalam beberapa cara yang sedikit berbeda, dan cara menentukan apa yang harus dilakukan didasarkan pada nilai parameter. Di dunia OOP, kita hanya akan membebani fungsi, tetapi ketika itu tidak mungkin maka Anda akhirnya melewati sekelompok bendera (atau sekelompok nilai, dan apakah mereka dilewati adalah bendera).

Saya pikir itu lebih mudah dibaca, sampai batas tertentu; tetapi seperti yang telah disebutkan orang lain, memiliki banyak parameter adalah bau kode, jadi saya tidak melihat banyak digunakan untuk ini dalam bahasa berorientasi objek seperti C #.

TMN
sumber