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

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, магическим образом решающей все ваши проблемы. Я бы посоветовал проанализировать их и, может быть, почерпнуть полезную информацию для себя.

Триває літнє зарплатне опитування. Чекаємо на вашу анкету — додайте зарплату. Це анонімно.

До обраного В обраному 0

Схожі статті Ruby для начинающих: чем интересен этот язык и как его эффективно изучать

Имея за плечами опыт преподавания (я вел курсы по Ruby в Spalah), я решил максимально доступно рассказать об этом языке программирования, поделиться опытом с начинающими специалистами и, возможно, заинтересовать кого-то из них Ruby. 71

Чому SOLID — важлива складова мислення програміста. Розбираємося на прикладах з кодом

На конкретних прикладах розглядаємо принципи SOLID. Іван Бранець, Solution Architect в EPAM Systems, просто та зрозуміло описує завдання, які допомагає розв’язати SOLID. Наприклад, як уникати залежностей між компонентами коду, який важко підтримувати. 118

«Копаючи картоплю, ви час від часу викопуєте ту, яку садив ще ваш батько і дід. Це legacy-код». Пояснюємо ІТ-терміни на прикладі садіння картоплі

Олександр Краковецький, CEO DevRain, пояснює ІТ-процеси, терміни та ролі на прикладі садіння картоплі. Якщо ви втомились від багатоповерхових конструкцій зі складними словами — ця стаття для вас. Просто і зрозуміло, а головне — дуже життєво. 35

DOU News #12

Найкращі коментарі пропустити

Однажды в одной газете мне попалась заметка о том, как следует выбирать рюкзак для путешествия. Советы, которые в ней давались, были вроде бы очень правильными, но абсолютно бесполезными: рюкзак должен быть легким, прочным, удобным и надежным. И недорогим — добавлю еще от себя очевидный совет.

Все советы, которые идут в формате «чуваки, ХХХ — это хорошо, делайте ХХХ» — из этой серии. Техника разработки — это всегда путь компромиссов, жертв и страданий. Даже в простейших решениях всегда есть аспект «быстрой выгоды против долгосрочного эффекта», неразрешимый абстрактно, без конкретного контекста и ситуации.

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

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

При том, что в большинстве советов есть зерно правды, вот навскидку «обратная сторона медали»:

Я не в том смысле, что это плохие советы. Они просто бесполезны вне контекста конкретного проекта и конкретного программиста.

Не работает. Человек может заболеть/уйти в отпуск/уволится. Тогда он становится узким местом в разработке (пример: один знает работу билинга — на него все молятся, ведь только он может его чинить). Команда вся должна быть в курсе всех частей проекта. Для решения подобных проблем используется система «review» кода перед принятием в основную ветку другим(и) разработчиком(ами). Также используется работа в паре и переключение с контекстных задач людей.

94 коментарі

Статья немного капитанская, пройдусь по пунктам, с которыми я не согласен.

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

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

Внешний комментарий:1. Бывает такое, что разраб чувствует себя МЕГГО-ОНОЛИТИГОМ и придумывает то, что пользователю :а) бесполезноб) не нужнов) ВАЩЕ не нужног) и даже мешаетТак что иногда лучше недобдеть, чем присобачить розовую кнопку посреди экрана, за которую цепляешься мышкой — ибо разраб подумал, что именно эта кнопка будет удобна для секретарши шефа для выпечатывания доков :)3. Во-во. пишите ЧО ПРОСЯТ. Если чего недопросили — допросят при тестировании :) Главное — быстрее отдавайте в это самое тестирование :)5. "Усложнять — просто, упрощать — СЛОЖНО«©какой-то гений — гуглите, кому интересно8. Не согласна. Задолбали проекты, которые делаются по методу «клади асфальт по направлению к стогу сена». Не можешь сам понять — выешь мозги архитектору и аналитику — но пойми. Или заставь их понять и потом объяснить. Либо делай только то, что максимально понятно. 9. Не поверите — при копипасте зачастую ЗАБЫВАЮТ половину функций скоммуниздить. в итоге имеем картину: «Юай тот же, но без перламутровых пуговиц кучи функционабельности» :( Так что и копиСпиСдить тоже надо уметь. чтобы не было мучительно больно потом сортировать г-но в выгребной яме :)14. Я бы поправила — разделяйте сферы ответственности и старайтесь не пересекать задачи Васи с первого этажа корпуса С с задачами Пети с четвертого этажа другой площадки :) Утрированно — но надеюсь поняли суть. Ибо по итогу к концу спринта обе задачи пришиты бантиками и держатся ровно до конца демо. .Остальное больше разрабовское — холиварьте без меня :)

Очень раздражает такая хрень:Например разработчик написал класс Doc и у него метод updateDocumentSum(). Мне надо понять как работает этот метод (как рассчитывается сумма) и почитать код этого метода.

Захожу в метод updateDocumentSum а там DocHelper.updateDocumentSum(). Окей лезу в класс DocHelper смотрю метод updateDocumentSum а там опять ссылка на другой класс — DocHelperMath.updateDocumentSum().

Тем не менее, это может быть обоснованно, хотя и не всегда.

Такой подход применяет Мартин Фаулер (Martin Fowler). Вы можете увидеть это в его книге «Рефакторинг. Улучшение существующего кода» («Refactoring. Improving the Design of Existing Code»). Русское издание — Санкт-Петербург, издательство «Символ-Плюс», 2013. Глава 1, страницы Особо обратите внимание на итоговую диаграмму взаимодействия после рефакторинга на рисунке 1.16 (страница 58). Он там построил как раз такую архитектуру.

Keep calm! Хорошего дня! :)

Суть проблемы кроется в отсутствии вменяемых или вообще любых javadoc-ов, которые есть во всех mature проектах. То что разработчику лень написать javadoc на модуль — не служит оправданием. Есть смысл перенять опыт Apache в плане документирования и внедрить у себя.

Автор не осилил event loop. Это очччень печально. В моем опыте все проэкты не начинавшиевся с эвент луп подлежали полной переписке на эвент луп.

Программист жалующийся на эвент луп это тоже самое что водитель жалующийся на рычаг коробки передач.

Советую взглянуть на golang.org/. html#goroutines , чтобы понять всю ущербность event loop’ов. Если сейчас не поймете, то не беда — с течением времени обязательно придет просветление :)

А сколько раз нужно почитать про goroutines, чтобы понять всю ущербность ивент лупов?

Нужно ли читать каждое утро, или лучше перед сном?

Хм. Почившие в Боге MxN треды?

А так ты сравниваешь теплое с мягким. И да — ты не умеешь водить автомобили с ручной КПП.

Собственные реализации ивент лупов обычно пишут начинающие разработчики, недавно прочитавшие устаревшую статью вроде The C10K problem, где утверждается, что для создания высокопроизводительного сервера, выдерживающего 10к запросов в секунду, обязательно нужно использовать ивент лупы. К счастью, с момента публикации данной статьи появились инструменты, скрывающие весь ужас разработки и отладки event state machine от обычных разработчиков и предоставляющих взамен намного более простую альтернативу — «один запрос — один поток», без существенного ущерба в производительноси и использовании системных ресурсов. Наиболее яркий пример такого инструмента — язык Go со встроенными goroutines.P.s. Создание собственных ивент лупов имеет право на жизнь, но только в очень узких областях, куда программирование высоконагруженных сервисов под интернет не входит.

Хм, я не разраб, конечно, но хочу добавить пару комментов:1). Автор — ярый поклонник agile. Ничего плохого в этом нет, но некоторые принципы, описанные здесь, при попытке использования в waterfall не дадут нечего, кроме лютого баттхёрта. Поэтому рекомендовал бы автору добавить что-то типа «agile projects only» в статью.2).

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

Порождает такое правило много неприятных вещей в проекте. Кроме «вдруг отпуск». 1. Человек ответственный за свой код. Верно. А тяжело узнать, кто что писал, глянув в историю системы контроля версий? И в пинг-понг кодом не получится играть. Поэтому ответственность — не оправдание.2. Такое разделение «дает право» не разбираться в других частях системы, за которые человек якобы не ответственнен. Появляется оправдание. И поэтому программисту не только «страшно» менять чужой код, он еще и делает много неверных предположений, как работает тот или иной модуль. И основываясь на неверных предположениях строит свой код. Это понятно, что в идеале модули должны быть почти не зависимы. Но в реале зависимости есть чуть ли не от температуры воздуха в помещении, где работают программисты. Связи между модулями могут быть даже во времени, не только в пространстве. Например, понимая как работает модуль и что там делают, можно понимать, что ожидается в будущем. Поэтому, например, знание всех модулей дает выше шансы, что не продублируете функционал.3. Страх перед правкой чужого кода заставляет программиста делать некоторые вещи не там где они должны быть в системе, а «на своей территории». Это какая-то дедовщина и неуставные отношения. Не будет работать рефакторинг, проект не может развиваться эволюционно. Ну как пример: что-то надо написать в базе данных, человек боится потревожить базовика или тот загружен, поэтому выгружает данные себе и производит обработку не там, где это должно быть.

Т.е. такое деление кода на зоны отвественности порождает строение архитектуры, связанное не с необходимостью, анализом требований, а с социально-психологическими аспектами.

PS. Веселое дополнение. Я как-то работал с легаси кодом, в котором классы помечались атрибутами, в которых указывался тот, кто писал класс. И по всему коду везде ловили исключения, чтобы отобразить окошко и показать виновного в «ошибке» )))

📎📎📎📎📎📎📎📎📎📎