Apakah parameter opsional bermanfaat atau menghambat pemeliharaan aplikasi? [Tutup]

14

Seperti yang dinyatakan dalam judul, apakah parameter opsional, seperti yang digunakan dalam C # membantu atau apakah mereka menjadi penghalang untuk pemeliharaan aplikasi dan harus dihindari karena dapat membuat kode lebih sulit untuk dipahami?

rjzii
sumber
3
Penafian: fitur bahasa apa pun di tangan yang salah dapat disalahgunakan. Jika suatu bahasa mengimplementasikan ini dengan cara yang cerdas, dan fitur bahasa ini tidak tumpang tindih dengan fitur bahasa yang ada dalam cara yang membosankan, maka mereka baik-baik saja, pada kenyataannya cukup berguna. Python memiliki beberapa param param packing / unpacking dan parameter lainnya "trik" (trik dalam arti yang baik, bukan Perl).
Ayub
Cobalah menulis aplikasi dalam C # yang terhubung ke Excel tanpa menggunakan parameter opsional. Itu akan menjawab pertanyaan Anda tanpa keraguan.
Dunk

Jawaban:

22

Parameter opsional, menurut pengalaman saya, adalah hal yang baik. Saya tidak pernah menemukan mereka membingungkan (setidaknya tidak lebih membingungkan daripada fungsi sebenarnya), karena saya selalu bisa mendapatkan nilai default dan tahu apa yang dipanggil.

Satu kegunaan untuk mereka adalah ketika saya harus menambahkan parameter lain ke fungsi yang sudah umum digunakan, atau setidaknya di antarmuka publik. Tanpa mereka, saya harus mengulang fungsi asli untuk memanggil satu yang punya argumen lain, dan itu bisa menjadi sangat tua jika saya akhirnya menambahkan argumen lebih dari sekali.

David Thornley
sumber
1
+1 Dan ini berharga dengan metode kelebihan beban yang menambahkan argumen seperti di new Circle(size, color, filled, ellipseProportions)mana sizedan colordiperlukan dan sisanya default.
Michael K
15

Secara umum, jika Anda sering membutuhkan banyak / parameter opsional, fungsi Anda terlalu banyak, dan harus dipecah. Anda kemungkinan melanggar SRP (Prinsip Tanggung Jawab Tunggal).

Cari parameter yang dapat dikelompokkan, misalnya (x dan y, menjadi titik).

Apakah parameter opsional ini ditandai dengan default? Jika Anda menggunakan flag, fungsi tersebut harus dipisah.

Itu tidak berarti Anda tidak boleh memiliki parameter opsional, tetapi secara umum, lebih dari satu atau dua parameter menyarankan bau kode.

Ini juga bisa menjadi petunjuk bahwa fungsi, sebenarnya harus kelas, dengan parameter opsional diubah menjadi properti, dan bagian parameter yang diperlukan dari konstruktor.

CaffGeek
sumber
1
+1 karena berhati-hati. Fitur apa pun, betapa pun baiknya, dapat disalahgunakan.
Michael K
3
Ini adalah saran yang bagus untuk menghasilkan kode ravioli rekayasa ulang di mana pengguna API Anda harus menggunakan setidaknya 6 kelas dan 15 fungsi untuk membuat hal yang paling sederhana terjadi.
dsimcha
1
@dsimcha, bagaimana Anda mendapatkannya dari apa yang saya tulis? Wow. Tolong jelaskan? Itu akan sama-sama desain yang buruk untuk memiliki "fungsi super" yang adalah apa yang Anda dapatkan ketika Anda memiliki banyak parameter opsional. Baca tentang prinsip-prinsip desain SOLID, dan penulisan kode yang dapat diuji. Lebih disukai menggunakan TDD. Kemudian kembali dan coba jelaskan kepada saya bahwa mengurangi parameter dalam fungsi adalah hal yang buruk.
CaffGeek
1
Kode yang dapat diuji bagus, tetapi begitu juga API yang bersih dan dapat digunakan yang tidak terlalu halus atau bertele-tele dan tidak menyurutkan kelas ke dalam situasi di mana fungsi adalah abstraksi yang tepat. Saya percaya pada prinsip tanggung jawab tunggal dengan tanggung jawab yang ditetapkan pada tingkat abstraksi yang tinggi. Jika tanggung jawab didefinisikan pada tingkat yang terlalu rendah, unit-unit individu menjadi terlalu disederhanakan sehingga interaksinya terlalu rumit.
dsimcha
1
@dsimcha, Anda tidak mengerti intinya. Unit individual harus tetap unit individual, dan tidak disatukan dalam satu fungsi. Itu juga tidak berarti mereka semua adalah fungsi yang dapat diakses publik. API Anda adalah pintu gerbang ke kode, dan harus bersih dan ringkas. Fungsi dengan beberapa parameter opsional tidak bersih, atau ringkas. Namun, kelebihan satu fungsi dengan parameter logis jauh lebih jelas. Misalnya, ada fungsi di banyak API di mana, dua parm adalah opsional, tetapi satu atau yang lain diperlukan. Apa yang jelas tentang itu ketika keduanya ditandai opsional?
CaffGeek
4

Parameter opsional baik-baik saja

Biasanya pembenarannya adalah bahwa a) Anda tahu Anda memiliki banyak argumen yang mungkin untuk metode Anda, tetapi Anda tidak ingin membebani karena takut mengacaukan API Anda, atau b) ketika Anda tidak tahu semua argumen yang mungkin tetapi Anda tidak ingin memaksa pengguna Anda untuk menyediakan array. Dalam setiap kasus, parameter opsional datang ke penyelamatan dengan cara yang rapi dan elegan.

Berikut ini beberapa contohnya:

1. Anda ingin menghindari kelebihan muatan dan tidak ingin menentukan array

Lihatlah printf () dari C, Perl, Java dll. Ini adalah contoh yang bagus dari kekuatan parameter opsional.

Sebagai contoh:

printf("I want %d %s %s",1,"chocolate","biccies");

printf("I want %d banana",1);

Tanpa kelebihan beban, tanpa array, sederhana dan intuitif (setelah Anda memahami kode format string standar). Beberapa IDE bahkan akan memberi tahu Anda jika string format Anda tidak cocok dengan parameter opsional Anda.

2. Anda ingin mengizinkan penggunaan default dan menyembunyikannya dari pengguna metode ini

sendEmail ("[email protected]");

Metode sendEmail mendeteksi bahwa berbagai nilai penting hilang dan mengisinya dengan menggunakan default yang ditentukan (subjek, tubuh, cc, bcc dll). API tetap bersih, namun fleksibel.

Catatan tentang terlalu banyak parameter

Namun, seperti yang dinyatakan orang lain, memiliki terlalu banyak parameter wajib untuk suatu metode menunjukkan bahwa Anda mungkin memiliki sesuatu yang salah dengan desain Anda. Ini terutama benar jika mereka berbagi jenis yang sama karena mereka dapat diaktifkan oleh pengembang secara tidak sengaja yang menyebabkan hasil aneh saat runtime:

String myMethod(String x, String y, String z, String a, int b, String c, int d) {}

adalah calon yang ideal untuk Mengenalkan Parameter Obyek refactoring untuk membuat

String myMethod(ParameterObject po) {}

class ParameterObject {
  // Left as public for clarity
  public String x;
  public String y;
  ... etc

}

Hal ini pada gilirannya dapat mengarah pada desain yang lebih baik berdasarkan pola Pabrik dengan spesifikasi yang disediakan sebagai objek parameter.

Gary Rowe
sumber
1
fungsi pemformatan string seperti printf adalah pengecualian dari aturan, orang dapat berargumen bahwa sementara mereka menggunakan daftar parameter opsional tanpa batas , itu lebih seperti argumen adalah array daripada parameter opsional, terlepas dari bagaimana penerapannya.
CaffGeek
@Chad, saya telah menyesuaikan jawaban saya untuk membedakan lebih baik antara parameter opsional dan ketika mereka beralih ke bau kode (seperti yang Anda sebutkan dalam jawaban Anda).
Gary Rowe
@Gary Rowe, terlalu banyak parameter opsional juga buruk dalam kebanyakan kasus.
CaffGeek
@Chad saya setuju, tetapi sebagian besar bahasa tidak menyediakan cara untuk menentukan batas jumlah argumen opsional sehingga merupakan pendekatan semua atau tidak sama sekali. Anda terpaksa menyerahkannya pada metode Anda untuk ditegakkan dan jelas jika metode Anda berurusan dengan 500 variabel maka itu pasti akan perlu di refactored.
Gary Rowe
@Gary Rowe, apa maksudmu "sebagian besar bahasa tidak menyediakan cara untuk menentukan batas jumlah argumen opsional"? Di sebagian besar bahasa, Anda menandainya, atau tidak memberikan nilai saat memanggil fungsi, tetapi header fungsi masih memiliki parameter yang ditentukan. Memang, dalam beberapa bahasa Anda dapat menambahkan sebanyak mungkin parameter yang Anda inginkan setelah Anda mengisi yang sudah ditentukan, tetapi saya rasa itu bukan jenis parameter opsional yang kita bicarakan di sini. (Terlepas dari pengecualian format string)
CaffGeek
2

Salah satu masalah dengan parameter default di C # (Saya berpikir batal DoSomething (int x = 1)) adalah mereka adalah konstanta. Itu berarti jika Anda mengubah default Anda harus mengkompilasi ulang setiap konsumen panggilan metode itu. Meskipun ini cukup mudah untuk dilakukan, ada kalanya berbahaya.

Po-ta-toe
sumber
1

Tergantung pada apa yang dilakukan kode Anda. Jika ada default yang masuk akal maka Anda harus menggunakan parameter opsional tetapi jika tidak ada default yang masuk akal maka menambahkan parameter opsional akan membuat kode Anda lebih rumit. Dalam banyak kasus, parameter opsional adalah cara yang rapi untuk menghindari nihil cek dan memotong logika percabangan. Javascript tidak memiliki parameter opsional tetapi ada cara untuk menirunya dengan || (Logis atau) dan saya menggunakannya sepanjang waktu ketika melakukan hal-hal yang berhubungan dengan database karena jika pengguna tidak memberikan nilai maka saya mengganti nilai saya sendiri dengan bantuan || yang menyelamatkan saya kesulitan menulis sejumlah jika pernyataan.

davidk01
sumber
1

Parameter opsional adalah cara terbaik untuk membuat hal-hal sederhana menjadi hal-hal yang sederhana dan rumit secara bersamaan. Jika ada standar wajar yang jelas yang diinginkan sebagian besar pengguna, setidaknya dalam kasus penggunaan cepat dan kotor, maka mereka tidak perlu menulis boilerplate untuk menentukannya secara manual setiap kali mereka memanggil fungsi Anda. Di sisi lain, jika orang mungkin punya alasan kuat untuk ingin mengubahnya, maka itu perlu diungkapkan.

Menggunakan kelas adalah IMHO solusi yang mengerikan, karena ini bertele-tele, tidak efisien, dan tidak konsisten dengan model mental tipikal dari apa yang dilakukan kelas. Fungsi adalah abstraksi yang sempurna untuk kata kerja, yaitu melakukan sesuatu dan kembali. Kelas adalah abstraksi yang tepat untuk kata benda, yaitu sesuatu yang memiliki keadaan dan dapat dimanipulasi dalam beberapa cara. Jika yang pertama harus menjadi model mental pengguna API, maka jangan membuatnya menjadi kelas.

dsimcha
sumber
1

Masalah dengan argumen opsional adalah bahwa orang cenderung hanya menyelipkan lebih banyak (dan lebih banyak) argumen ke fungsi daripada mengekstraksi kode yang relevan ke dalam fungsi baru. Ini diambil secara ekstrim di php . Contohnya:

bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
                      [, mixed $arg = SORT_REGULAR [, mixed $... ]]] )
Martin Wickman
sumber
1

Parameter opsional pada dasarnya merupakan cara berbeda untuk kelebihan fungsi. Jadi ini pada dasarnya bermuara pada: "Apakah kelebihan fungsi buruk"?

Pieter B
sumber
1

Saya awalnya menyukai fitur ini dengan python, dan menggunakannya untuk 'memperluas' metode yang sudah digunakan. Dan itu terlihat bagus dan mudah, tetapi segera kembali; karena ketika saya menambahkan parameter opsional, ini memodifikasi perilaku metode yang sudah ada yang diandalkan oleh klien lama dan dengan cara yang tidak ditangkap oleh kasus uji unit yang ada. Pada dasarnya melakukan ini melanggar Prinsip Terbuka Tertutup; kode terbuka untuk ekstensi tetapi ditutup untuk modifikasi. Jadi saya percaya menggunakan fitur ini untuk mengubah kode yang ada bukanlah ide yang baik; tapi oke kalau digunakan dari awal

Alex Punnen
sumber
0

Saya pikir akan lebih baik untuk membebani suatu fungsi dengan tanda tangan yang berbeda (yaitu parameter) daripada menggunakan parameter opsional.

Kode keras
sumber
Mengapa? Saya pikir ini lebih bersih jika Anda dapat menggabungkan banyak metode kelebihan beban menjadi satu metode menggunakan params default jika semua metode memiliki fungsi dasar yang sama
Amit Wadhwa
Anda bisa memikirkan itu. Saya bukan orang yang berpikir Microsoft melakukan semuanya dengan cara yang benar, tetapi jika Anda akurat, maka saya tidak akan pernah melihat kelebihan ketika menggunakan kerangka NET., Hanya satu tanda tangan fungsi besar - seperti di VB6 ol '.
HardCode