Як зазначено в заголовку, чи не корисні параметри, наприклад ті, що використовуються в C #, або вони перешкоджають обслуговуванню додатків, і їх слід уникати, оскільки вони можуть зробити складніше зрозумілий код?
Як зазначено в заголовку, чи не корисні параметри, наприклад ті, що використовуються в C #, або вони перешкоджають обслуговуванню додатків, і їх слід уникати, оскільки вони можуть зробити складніше зрозумілий код?
Відповіді:
Додаткові параметри, на мій досвід, були гарною справою. Я ніколи не знаходив їх заплутаними (принаймні, не більш заплутаними, ніж фактична функція), оскільки я завжди можу отримати значення за замовчуванням і знати, що викликається.
Одне використання для них - це коли я маю додати ще один параметр до функції, яка вже є загальною, або принаймні у загальнодоступному інтерфейсі. Без них мені доведеться повторити оригінальну функцію, щоб викликати ту, яка має інший аргумент, і ця може стати справді старою, якщо я закінчую додавання аргументів не один раз.
new Circle(size, color, filled, ellipseProportions)
де size
і color
потрібно, а решта - за замовчуванням.
Загалом, якщо вам часто потрібно багато / необов'язкових параметрів, ваші функції роблять занадто багато, і їх слід розбити. Ви, ймовірно, порушуєте SRP (єдиний принцип відповідальності).
Шукайте параметри, які можна згрупувати, наприклад (x і y, станьте точкою).
Чи є ці необов'язкові параметри прапорцями за замовчуванням? Якщо ви використовуєте прапори, функцію слід розділити.
Це не означає, що ви ніколи не повинні мати необов'язкові параметри, але загалом більше одного-двох параметрів свідчать про запах коду.
Це також може бути підказкою, що функція насправді повинна бути класом із необов'язковими параметрами, зміненими на властивості, а необхідні параметри - частиною конструктора.
Необов’язкові параметри просто чудові
Зазвичай виправданням є або те, що: a) ви знаєте, що у вас є багато можливих аргументів для вашого методу, але ви не хочете перевантажуватися, боячись затиснути API, або b) коли ви не знаєте всіх можливих аргументів, але ви не хочуть змушувати свого користувача надати масив. У кожному випадку необов'язкові параметри приходять на допомогу акуратно та елегантно.
Ось кілька прикладів:
1. Ви хочете уникнути перевантаження і не хочете вказувати масив
Погляньте на printf () від C, Perl, Java тощо. Це чудовий приклад потужності необов'язкових параметрів.
Наприклад:
printf("I want %d %s %s",1,"chocolate","biccies");
printf("I want %d banana",1);
Без перевантаження, без масивів, просто та інтуїтивно зрозуміло (як тільки ви зрозуміли коди стандартного рядка). Деякі IDE навіть повідомлять, чи ваш форматний рядок не відповідає вашим необов'язковим параметрам.
2. Ви хочете дозволити використання за замовчуванням і зберегти їх прихованими від користувача методу
sendEmail ("test@example.org");
Метод sendEmail виявляє, що різні істотні значення відсутні, і заповнює їх за допомогою визначених значень за замовчуванням (тема, тіло, копія, копія та ін.). API підтримується чистим, але гнучким.
Примітка про занадто багато параметрів
Однак, як заявили інші, занадто багато обов'язкових параметрів методу вказує на те, що у вас, ймовірно, щось не так з вашим дизайном. Це особливо справедливо, якщо вони мають один і той же тип, оскільки розробник може перемикатися випадково, що призводить до дивних результатів під час виконання:
String myMethod(String x, String y, String z, String a, int b, String c, int d) {}
є ідеальним кандидатом для створення рефакторингу об'єкта введення параметра
String myMethod(ParameterObject po) {}
class ParameterObject {
// Left as public for clarity
public String x;
public String y;
... etc
}
Це, в свою чергу, може призвести до кращого дизайну на основі заводського зразка з наданою специфікацією в якості об'єкта параметра.
Однією з проблем із параметрами за замовчуванням у C # (я думаю, що недійсне DoSomething (int x = 1)) - це константи. Це означає, що якщо ви зміните типовий засіб, вам доведеться перекомпілювати будь-яких споживачів цього виклику методу. Хоча це зробити досить просто, є випадки, коли це небезпечно.
Це залежить від вашого коду. Якщо є розумні за замовчуванням, то слід використовувати необов’язкові параметри, але якщо немає розумних значень за замовчуванням, додавання додаткових параметрів ускладнить ваш код. У багатьох випадках необов'язкові параметри є акуратним способом усунення нульових перевірок та вирізання логіки розгалуження. У Javascript немає необов'язкових параметрів, але є спосіб емуляції їх за допомогою || (логічно або), і я використовую це весь час, коли роблю речі, пов'язані з базою даних, тому що якщо користувач не надає певного значення, то я підміняю власні значення за допомогою || що врятує мені клопоту написати цілу купу, якщо тоді заяв.
Необов’язкові параметри - це чудовий спосіб зробити прості речі простими і складними речами можливими одночасно. Якщо є чіткий розумний дефолт, який бажає більшість користувачів, принаймні у випадках швидкого та брудного використання, тоді вони не повинні писати котлові, щоб вручну вказувати її кожен раз, коли вони викликають вашу функцію. З іншого боку, якщо люди можуть мати вагомі причини для того, щоб змінити це, то це потрібно піддавати впливу.
Використання класу IMHO - жахливе рішення, оскільки воно є багатослівним, неефективним та невідповідним типовій ментальній моделі того, що робить клас. Функція - це ідеальна абстракція дієслова, тобто щось робити і повертатися. Клас - це правильна абстракція іменника, тобто те, що має стан і може маніпулювати кількома способами. Якщо перша повинна бути ментальною моделлю користувача API, тоді не робіть це класом.
Проблема з необов'язковими аргументами полягає в тому, що люди прагнуть просто підтягувати все більше (і більше) аргументів функції замість вилучення відповідного коду в нову функцію. Це до кінця в php . Наприклад:
bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
[, mixed $arg = SORT_REGULAR [, mixed $... ]]] )
Я спочатку любив цю функцію в python і використовував її для 'розширення' вже використаних методів. І це виглядало приємно і легко, але скоро відкусилося; тому що, коли я додав необов'язковий параметр, це модифікувало поведінку існуючого методу, на який покладався старий клієнт, і таким чином, який не був схоплений існуючими тестовими випадками одиниці. По суті, це - порушення принципу відкритого закритого типу; код відкритий для розширення, але закритий для модифікації. Тому я вважаю, що використання цієї функції для зміни існуючого коду - не дуже гарна ідея; але добре, якщо його використовувати з самого початку
Я думаю, було б краще перевантажити функцію різними підписами (тобто параметрами), ніж використовувати необов'язкові параметри.