Как не быть тем парнем, а писать функции лучше

1
8772
Добавить в избранное

Понятные и поддерживаемые функции – не миф. Используйте эти 4 главных принципа написания кода, и товарищи по команде скажут «спасибо».

Как не быть тем парнем, а писать функции лучше

У каждого разработчика найдётся история о проблемах с пониманием кода, который достался в наследство в конкретном проекте. Не обошло это и вас, верно? 😉

Так было с Федей, который подолгу рассказывал, как он раздражён и устал пялиться на бессмысленную функцию-мастодонта. На вопрос, не пытался ли он уточнить это у товарища по команде, который работал над программным обеспечением до него, он ответил с лёгким смешком: «(Имя товарища по команде) тоже без понятия. Он смотрел на код так же внимательно и сказал, что не писал этого».

Как не быть тем парнем, а писать функции лучше

После разговора с Федей программист осознал две вещи. Первым было: «Не будь тем парнем!». Значит не походи на человека, который заставил страдать Федю. Вторым было: «Пиши функции лучше». Это единственный способ не быть тем парнем.

Сто процентов, нет числа таким Фёдорам, которым приходится наследовать, осмысливать и рефакторить ужасно написанные функции в программных проектах. Правильно разработанное программное обеспечение заботится о небольших единицах (или методах), то есть функциях на микроуровне, а не только об общей функциональности на макроуровне.

Раз так часто пишем ужасные функции, пора задуматься об улучшении в этой конкретной области. Ниже приводятся некоторые руководящие принципы и подходы опытных специалистов, коллег и других рекомендуемых источников.

Введение

Определение вещей – логичное начало. Функции – запрограммированные операции. Если хочется больше слов, переходим в Google. Программные системы состоят из функций в разной степени. Возможно, разрабатываем программное обеспечение в объектно-ориентированном стиле, в котором функции живут внутри классов, составляющих систему, и влияют на состояние соответствующих классов. Или система использует функционально-ориентированную парадигму и разбита на набор взаимодействующих централизованно функций. Независимо от подхода, функции остаются, потому что не обойтись без декомпозиции решения. И на очень низком уровне разделения находим эти небольшие единицы, которые помогают достичь конкретной цели.

Функции должны быть маленькими

И всё-таки размер имеет значение.

Маленькие функции легки для чтения, понимания, тестирования и отладки. Не будем называть магическое число. Некоторые эксперты скажут не больше 15 строк, другие – не больше 25. Это, вероятно, придётся решать в каждой команде. Важно помнить причины сохранения маленького размера функций.

Удобочитаемость: функция, как правило, состоит из сигнатуры и блока кода, который выполняется при вызове или запуске функции. Чем меньше строк кода в блоке функции, тем легче прочитать и понять, что функция делает.

Понятность: меньшие функции помогают снизить вероятность отклонения от главного назначения функции. Чем более линейное назначение, тем понятнее.

Тестируемость: у коротких методов меньше вариаций, что означает, их легче тестировать.

Вот пример функции, предназначенной для проверки правильности токена:

Функции должны быть чистыми

Да, звучит неоднозначно. Однако речь идёт не столько о стиле кода, отступах или длине имён переменных. Речь идёт о понятности. Сможет ли Федя взглянуть на вашу функцию, понять её смысл и внести изменения, не убив дни работы?

Важно, насколько поддерживаемый будет ваш код, ведь поддерживаемый код составляет каркас поддерживаемого программного обеспечения. Для определения чистоты кода используются и другие атрибуты, которые субъективны, и решаются лично или в команде.

Функции должны быть простыми

Технический руководитель часто говорит: «Если это (функция) требует больших усилий, остановитесь и переосмыслите решение». В нашей области усилия чаще не приветствуются, потому что порождают нечто сложное.

«В разработке программного обеспечения усилия не растут линейно со сложностью – они растут в геометрической прогрессии. Поэтому легче управлять двумя наборами из четырёх сценариев в каждом, чем одним с шестью ». – Abraham Marín-Pérez

Если писать функции на основе модульности и сокращать пути выполнения, будет намного проще понять их назначение. Когда пишут сложный код, его гораздо труднее понять, и подобные недоразумения часто приводят к ошибкам.

Вот пример функции, которая проверяет, что полученный аргумент – массив строк:

Функции должны быть однозадачными (без побочных эффектов)

Роберт Мартин лучше выразил это в «Чистом коде»: «Функция обещает сделать одну вещь…», и, следовательно, так и должно быть. Наличие побочных эффектов только делает код менее читаемым из-за изменений в блоке кода, которые не приводят к достижению этой конкретной цели. Функции должны быть основаны на детерминированном алгоритме – при заданных входных данных возвращать один и тот же результат.

Как не быть тем парнем, а писать функции лучше

Возьмём следующий пример: функция предназначена для получения даты и недели, где дата встречается, в виде массива с объектами даты.

Говорят, что у функции, как правило, одна цель. Однако, возможно, заметили момент, когда генерируем неделю на основе двух аргументов: объекта (в данном случае объекта Moment) и дня недели (воскресенье, понедельник, вторник и т. д.). Таким образом, лучше создать новую функцию для упрощения и сделать методы более линейными относительно назначения.

Когда разделим функцию на две части, получаем следующее:

В результате случайному программисту теперь проще понять смысл наших функций, создать для них контрольные примеры и изменить их при необходимости.

Заключение

Эти рекомендации – не единственные, однако закладывают крепкое основание для создания классного кода при написании функций. Кроме того, это потребует практики, обдуманного рефакторинга и взгляда со стороны (рецензий). Покажется, что нужны дополнительные усилия для создания такого рода кода, но это того стоит. Эдсгер Дейкстра, крёстный отец программирования, сказал следующее:

«В программировании элегантность – не дополнительная роскошь, а качество, которое определяет успех и неудачу».

Не будь тем парнем, пиши функции лучше.

Оригинал

А каким принципам написания функций следуете вы?

Хотите получать больше интересных материалов с доставкой?

Подпишитесь на нашу рассылку:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




Один комментарий

  1. Александр Егоров

    Еще надо не лениться оставлять комментарии: 1) к самой функции в целом 2) к конкретным кускам внутри реализации. Касаемо п.2 речь не только о том, ЧТО делает этот кусок (хотя это порой тоже нужно, чтобы коллега смог быстрее понять, что происходит), но и о том, ПОЧЕМУ было решено сделать именно так.

Добавить комментарий