14 рекомендаций из личного опыта для разработчиков

На DOU попалась интересная статья: 14 рекомендаций из личного опыта для разработчиков.

Всем привет. Я как разработчик с небольшим стажем хочу поделиться рекомендациями, которые могут оказаться полезными некоторым из вас. Чем опытнее разработчик, тем большее количество перечисленных ниже советов покажется ему очевидными и банальными. Для новичков некоторые пункты могут показаться идущими вразрез со здравым смыслом. В этом нет ничего страшного — опыт лечит :)

Рекомендации

1. ПИШИТЕ ТОЛЬКО ТОТ КОД, КОТОРЫЙ ВАМ ДЕЙСТВИТЕЛЬНО НЕОБХОДИМ В ДАННЫЙ МОМЕНТ (ПРИНЦИП YAGNI)

Неиспользуемый код появляется из-за следующих «отмазок»:

  • «В будущем нам точно понадобится данная функциональность. Почему бы не реализовать ее прямо сейчас?»
  • «Данная абстракция выглядит незавершенной без этой функциональности, которая сейчас не используется. Но ведь в будущем она обязательно будет использоваться!»

Код «про запас» плох по следующим причинам:

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

2. БЕЗЖАЛОСТНО УДАЛЯЙТЕ УСТАРЕВШИЙ КОД

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

3. НАЧИНАЙТЕ НОВЫЙ ПРОЕКТ С МИНИМАЛЬНОГО НАБОРА ФУНКЦИОНАЛЬНОСТИ (MINIMUM VIABLE PRODUCT)

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

4. ПРОВОДИТЕ ПОСТОЯННЫЙ РЕФАКТОРИНГ

Любому успешному развивающемуся проекту свойственны две постоянные тенденции:

  • Ухудшение качества кода за счет неизбежного добавления новых свистелок с перделками.
  • Появление новых возможностей для рефакторинга, приводящего к повышению качества кода.

Очевидно, что качество кода в развивающемся проекте может удержаться только с помощью постоянного рефакторинга. Если «забыть» про рефакторинг, то с течением времени проект превратится в говнокод, с которым никто не захочет иметь дела. Это может привести к остановке его развития.

5. ПРЕДПОЧИТАЙТЕ ПРОСТЫЕ РЕШЕНИЯ СЛОЖНЫМ (ПРИНЦИП KISS)

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

6. ТУПОЙ, НО ПОНЯТНЫЙ КОД ВСЕГДА ЛУЧШЕ ГЕНИАЛЬНОГО, НО ЗАПУТАННОГО

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

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

7. НЕ ЗАГРОМОЖДАЙТЕ ПРОЕКТ НЕНУЖНЫМИ АБСТРАКЦИЯМИ В ВИДЕ ПРОМЕЖУТОЧНЫХ API, ФРЕЙМВОРКОВ, КЛАССОВ И ИНТЕРФЕЙСОВ

Следующие признаки позволяют выявить ненужные абстракции:

  • Если для реализации новой функциональности, не предусмотренной в абстракции, приходится переписывать пол-проекта, то во время переписывания смело удаляйте такую абстракцию.
  • Если абстракция существенно усложняет отладку кода, то быстрее выпиливайте ее из проекта.
  • Если только один человек на проекте может корректно использовать предоставленный абстракцией API, то есть повод задуматься о смысле ее существования. В большинстве случаев таким человеком является автор абстракции.
  • Если проблемы, связанные с использованием абстракции, исправляются методом случайных правок кода, то что-то не так с этой абстракцией.
  • Если новичкам на проекте приходится тратить более недели на изучение правильного использования, слишком заумной абстракции, то стоит подумать над ее упрощением или полным отказом от нее.
  • Если объем полезного для проекта кода, содержащегося в абстракции и в местах ее использования, составляет лишь небольшую часть от объема вспомогательного кода, то лучше заменить абстракцию парой простых в использовании функций.
  • Если спрятанный за абстракцией функционал проще использовать напрямую, минуя абстракцию, то с большой долей вероятности данная абстракция превратится в leaky abstraction, сделав бессмысленным собственное существование.

8. НЕ ПЫТАЙТЕСЬ ПРОДУМАТЬ АРХИТЕКТУРУ НОВОГО ПРОЕКТА ИЛИ «ФИЧИ» ДО МЕЛОЧЕЙ ПЕРЕД ЕЕ РЕАЛИЗАЦИЕЙ

Лучше потратить один день на создание работающего прототипа с не очень качественным кодом, чем полгода на продумывание «идеальной» архитектуры. Как показывает практика, в обоих случаях придется переписывать почти все с нуля. Отличие лишь в том, что в первом случае мы можем за оставшиеся полгода «вылизать» архитектуру, идеально подходящую для практических нужд. А во втором случае спустя полгода у нас будет лишь сферический конь в вакууме, вряд ли идеально работающий на практике.

9. НЕ БОЙТЕСЬ КОПИПАСТЫ

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

10. НЕ ПЫТАЙТЕСЬ СИЛЬНО ОПТИМИЗИРОВАТЬ КОД ДО ТОГО, КАК ОН НАЧНЕТ ТОРМОЗИТЬ IRL

Оптимизируйте только найденные с помощью профилирования узкие места. Обычно они составляют максимум пару процентов от всего кода. Это не означает, что по коду нужно специально разбрасывать O(n) алгоритмы вместо O(1) алгоритмов. Но и выжимать максимум из всех подряд алгоритмов в коде не стоит — зря потратите время (т.к. абсолютное большинство «ускоренных» алгоритмов будут редко исполняться на практике) а также можете ухудшить качество кода слишком «умными» алгоритмами.

11. НЕ ТРАТЬТЕ МНОГО ВРЕМЕНИ НА HIGHLY SCALABLE АРХИТЕКТУРУ В НОВЫХ ПРОЕКТАХ

Как показывает практика, абсолютное большинство новых проектов никогда не выходят за рамки пары-тройки серверов. Так зачем тратить время на high scalability там, где она с вероятностью 99.999% не понадобится? Если же вашему проекту повезет и его посещаемость начнет стремительно приближаться к посещаемости Facebook, то у вас появится достаточно средств для оплаты работы лучших специалистов по высоконагруженным системам, чтобы они в минимально сжатые сроки адаптировали вашу архитектуру под миллиард одновременных посетителей.

12. ЛУЧШЕ ИМЕТЬ 10 РАЗЛИЧНЫХ ПРОСТЫХ В ИСПОЛЬЗОВАНИИ ФУНКЦИЙ, ПРИНИМАЮЩИХ ПО ОДНОМУ-ДВА ПАРАМЕТРА, ЧЕМ ОДНУ ФУНКЦИЮ-ШВЕЙЦАРСКИЙ НОЖ, ПРИНИМАЮЩУЮ 5 ОБЯЗАТЕЛЬНЫХ И 5 ОПЦИОНАЛЬНЫХ ПАРАМЕТРОВ

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

13. СТАРАЙТЕСЬ ДАТЬ ВСЕМ ПУБЛИЧНЫМ ИДЕНТИФИКАТОРАМ В КОДЕ (МОДУЛЯМ, КЛАССАМ, ФУНКЦИЯМ, ПЕРЕМЕННЫМ) РАЗНЫЕ ИМЕНА, ДАЖЕ ЕСЛИ ОНИ ПРИНАДЛЕЖАТ РАЗЛИЧНЫМ КЛАССАМ/МОДУЛЯМ/БИБЛИОТЕКАМ/ПАКЕТАМ

Тупой совет? Для кого как. Мне он помогает быстро найти все места использования конкретного идентификатора в коде с помощью программы grep :) Если вы думаете, что это приведет к слишком длинным идентификаторам в крупных проектах, то это тоже не так — см., например, код ядра linux, состоящий из десятков миллионов строк.

14. ЧЕТКО РАЗДЕЛЯЙТЕ ОТВЕТСТВЕННОСТЬ — ЗА КАЖДЫЙ УЧАСТОК КОДА ДОЛЖЕН ОТВЕЧАТЬ ОДИН РАЗРАБОТЧИК

Если на проекте работает несколько разработчиков, то желательно четко разделить обязанности. Это даст следующие преимущества по сравнению с общим (т.е. ничьим) кодом:

  • Каждый адекватный разработчик будет стараться поддерживать качество кода, за который он отвечает.
  • Если сторонний разработчик попытается редактировать чужой код, то будет немедленно выявлен и «наказан» хозяином.
  • Каждый разработчик с течением времени станет «профи» на своем участке.
  • Разработчики не смогут играть в пинг-понг с багами, ссылаяь на то, что «это не мой код».
  • Все это приведет к улучшенному качеству кода, к снижению количества багов и к ускоренному внедрению новых «фич».

Заключение

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

 
comments powered by Disqus