HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>В динамических языках есть два основных подхода при проектировании входных параметров функций: первый - использовать явные, позиционные аргументы, и второй - передавать структуру, внутри которой должно находиться все то, что ожидает функция. Явный и неявный способы передачи одинаково часто встречаются в реальном коде и, при этом, не всегда понятно, какой способ стоит предпочесть для конкретной функции. Именно об этом мы и поговорим.</p>
1 <p>В динамических языках есть два основных подхода при проектировании входных параметров функций: первый - использовать явные, позиционные аргументы, и второй - передавать структуру, внутри которой должно находиться все то, что ожидает функция. Явный и неявный способы передачи одинаково часто встречаются в реальном коде и, при этом, не всегда понятно, какой способ стоит предпочесть для конкретной функции. Именно об этом мы и поговорим.</p>
2 <p>Для начала рассмотрим один простой пример - функцию, которая находит максимальное число среди переданных:</p>
2 <p>Для начала рассмотрим один простой пример - функцию, которая находит максимальное число среди переданных:</p>
3 <p>Явные параметры делают код самодокументируемым: по сигнатуре функции сразу понятно, какие аргументы ожидаются. А хорошие названия подсказывают их типы. Небольшое удобство добавляет метод apply, с помощью которого удобно вызывать функцию, если сами параметры хранятся в массиве:</p>
3 <p>Явные параметры делают код самодокументируемым: по сигнатуре функции сразу понятно, какие аргументы ожидаются. А хорошие названия подсказывают их типы. Небольшое удобство добавляет метод apply, с помощью которого удобно вызывать функцию, если сами параметры хранятся в массиве:</p>
4 <p>Теперь про недостатки. Главный недостаток - в жесткой завязке на аргументы. При изменении количества аргументов, включая добавление и удаление параметров по умолчанию, придется переписывать все места, где функция используется. Особенно это актуально в случае высокоуровневых функций, сквозь них проходит множество данных:</p>
4 <p>Теперь про недостатки. Главный недостаток - в жесткой завязке на аргументы. При изменении количества аргументов, включая добавление и удаление параметров по умолчанию, придется переписывать все места, где функция используется. Особенно это актуально в случае высокоуровневых функций, сквозь них проходит множество данных:</p>
5 <p>При использовании неявных аргументов ситуация меняется на противоположную. Резко падает уровень самодокументируемости. Без описания или анализа содержимого функции сложно понять, что ей можно передавать. С другой стороны, у таких функций редко меняется определение, так как количество передаваемых данных расширяется автоматически:</p>
5 <p>При использовании неявных аргументов ситуация меняется на противоположную. Резко падает уровень самодокументируемости. Без описания или анализа содержимого функции сложно понять, что ей можно передавать. С другой стороны, у таких функций редко меняется определение, так как количество передаваемых данных расширяется автоматически:</p>
6 <p>Какой способ лучше в той или иной ситуации? Исходя из вышесказанного, можно заметить, что явные аргументы лучше всего работают с простыми и низкоуровневыми функциями, например математическими. Именно поэтому все функции для работы со строками или числами во всех языках имеют явные аргументы. То же самое касается практически всех остальных встроенных функций и методов.</p>
6 <p>Какой способ лучше в той или иной ситуации? Исходя из вышесказанного, можно заметить, что явные аргументы лучше всего работают с простыми и низкоуровневыми функциями, например математическими. Именно поэтому все функции для работы со строками или числами во всех языках имеют явные аргументы. То же самое касается практически всех остальных встроенных функций и методов.</p>
7 <blockquote><p>Подписывайтесь на<a>канал Кирилла Мокевнина в Telegram</a>- чтобы узнать больше о программировании и профессиональном пути разработчика</p>
7 <blockquote><p>Подписывайтесь на<a>канал Кирилла Мокевнина в Telegram</a>- чтобы узнать больше о программировании и профессиональном пути разработчика</p>
8 </blockquote><p>Это относится и к пользовательским функциям, которые имеют четкую, редко меняющуюся структуру. Обычно с небольшим числом аргументов.</p>
8 </blockquote><p>Это относится и к пользовательским функциям, которые имеют четкую, редко меняющуюся структуру. Обычно с небольшим числом аргументов.</p>
9 <p>С неявными чуть сложнее. Вот список ситуаций, в которых их использовать лучше:</p>
9 <p>С неявными чуть сложнее. Вот список ситуаций, в которых их использовать лучше:</p>
10 <ul><li><p>Когда функция не использует передаваемые данные напрямую, а транслирует их дальше по цепочке вызовов. В такой ситуации явные аргументы будут только мешать из-за необходимости их постоянно править, при том, что функция ими не пользуется.</p>
10 <ul><li><p>Когда функция не использует передаваемые данные напрямую, а транслирует их дальше по цепочке вызовов. В такой ситуации явные аргументы будут только мешать из-за необходимости их постоянно править, при том, что функция ими не пользуется.</p>
11 </li>
11 </li>
12 <li><p>Когда данных много и, особенно, если они могут часто меняться в процессе. Или среди этих параметров много необязательных. Пример с пользователем как раз об этом. Нередко данные в таких ситуациях приходят в виде объекта (ассоциативного массива) и их, в принципе, удобнее передавать всем скопом сразу. Кроме того, такой подход часто используют для конфигурирования:</p>
12 <li><p>Когда данных много и, особенно, если они могут часто меняться в процессе. Или среди этих параметров много необязательных. Пример с пользователем как раз об этом. Нередко данные в таких ситуациях приходят в виде объекта (ассоциативного массива) и их, в принципе, удобнее передавать всем скопом сразу. Кроме того, такой подход часто используют для конфигурирования:</p>
13 </li>
13 </li>
14 <li><p>Библиотечные функции, которые могут работать с произвольными параметрами и структурами. Частая ситуация - это ORM или библиотека для запросов к какой-нибудь системе, например, GitHub. В этой ситуации разработчик библиотеки просто не знает и часто не может знать, что и как собирается делать пользователь, поэтому оставляет конкретное наполнение на усмотрение тех, кто использует его код:</p>
14 <li><p>Библиотечные функции, которые могут работать с произвольными параметрами и структурами. Частая ситуация - это ORM или библиотека для запросов к какой-нибудь системе, например, GitHub. В этой ситуации разработчик библиотеки просто не знает и часто не может знать, что и как собирается делать пользователь, поэтому оставляет конкретное наполнение на усмотрение тех, кто использует его код:</p>
15 </li>
15 </li>
16 </ul><p>В некоторых языках, таких как python или ruby, существуют специальные именованные параметры. Они явно прописываются в определении как позиционные параметры, что делает их самодокументируемыми, с другой стороны, их можно передавать в любом порядке указывая имя параметра при вызове. Такой способ не заменяет остальные, но делает код проще в некоторых случаях.</p>
16 </ul><p>В некоторых языках, таких как python или ruby, существуют специальные именованные параметры. Они явно прописываются в определении как позиционные параметры, что делает их самодокументируемыми, с другой стороны, их можно передавать в любом порядке указывая имя параметра при вызове. Такой способ не заменяет остальные, но делает код проще в некоторых случаях.</p>
17 <p>Но не все ситуации можно так легко разложить. Там, где непонятно, что делать, рекомендуется работать с явными аргументами, и только потом по необходимости переходить к неявным. Главный ориентир - здравый смысл.</p>
17 <p>Но не все ситуации можно так легко разложить. Там, где непонятно, что делать, рекомендуется работать с явными аргументами, и только потом по необходимости переходить к неявным. Главный ориентир - здравый смысл.</p>
18 <h2>Дополнительные материалы:</h2>
18 <h2>Дополнительные материалы:</h2>
19 <ul><li><a>Проектирование параметров функций</a></li>
19 <ul><li><a>Проектирование параметров функций</a></li>
20 <li><a>Проектирование функций</a></li>
20 <li><a>Проектирование функций</a></li>
21 </ul>
21 </ul>