Come work in Estonia – the most advanced digital society. Many Ukrainians already know that Estonia is affordable – become one of them and check out the jobs available!
×Закрыть

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

Tips image via Shutterstock.

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

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

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

Лучшие комментарии пропустить

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

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

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

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

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

1. Пишите только тот код, который вам действительно необходим в данный момент
Так, вероятно, можно получить фичу быстрее. Но — придется переписывать код потом каждый раз, когда прилетают изменения. Причем не только по функционалу — а еще и по другим фичам, которые в той или иной степени касаются этого кода.
Таким образом, если пытаться заглянуть в очень далекое будущее — решение будет слишком сложным. Если не видеть дальше своего носа — слишком простым. Очевидно, где-то между этими значениями функция достигает максимума. Где бы?
3. Начинайте новый проект с минимального набора функциональности
Звучит круто, но как же понять, какой набор — минимальный? Джобс, например, придерживался обратного принципа, выпускал продукты только достигшие эффектного состояния — и немало преуспел. Может не все так просто, может есть и альтернативы?
4. Проводите постоянный рефакторинг
Постоянный рефакторинг = постоянные затраты времени девелоперов не приносящее никакой новой функциональности. Возможно, еще и потому, что многое было сделано «с минимальным набором фич» и «настолько просто, насколько возможно». Может, это не принцип, а неспособность предвидеть на минимально внятное время? Предполагаю, что если экстремально увлечься идеями YAGNI, KISS и MVP можно с определенного момента времени тратить вообще все время только на рефакторинг.
5. Предпочитайте простые решения сложным
От простого до убогого — один шаг. Как понять, что он не сделан? Все должно быть сделано насколько просто, насколько возможно, но не проще!
6. Тупой, но понятный код всегда лучше гениального, но запутанного
Я бы поостерегся использовать слово «всегда». Не говоря уже о странной пресуппозиции того, что «тупой» может быть «понятным» в то время как «гениальный» является «запутанным».
Я бы понял, если бы совет звучал как, например «читаемость кода важнее его производительности». А так — теряюсь в догадках. Кроме того, тут тоже надо понимать, когда остановиться.
7. Не загромождайте проект ненужными абстракциями в виде промежуточных API, фреймворков, классов и интерфейсов
Как же понять, какая абстракция — ненужная? «Если абстракция существенно усложняет отладку кода, то быстрее выпиливайте ее из проекта.» — а если при этом добавляет суперфичу на весь проект? У нас цель-то конечная какая? «Если новичкам на проекте приходится тратить более недели на изучение правильного использования, слишком заумной абстракции, то стоит подумать над ее упрощением или полным отказом от нее» — стоило об этом подумать, когда вы ее писали. Раз уж написали — наверное, для этого были причины. Является ли неделя новичка более весомой причиной? Сомневаюсь.
Любой новый фреймворк вызывает недели и месяцы изучения у любого программиста — значит ли это, что он — ненужная абстакция?
8. Не пытайтесь продумать архитектуру нового проекта или «фичи» до мелочей перед ее реализацией
Вы уже дали этот совет под номером один — проблема та же. Думать слишком мало — плохо, думать слишком много — плохо, сколько в самый раз — непонятно. То, что не надо бросаться в крайности — это не новость. Лучше расскажите, как попасть в самую мякотку.
9. Не бойтесь копипасты
Бойтесь копипасты! Копирование кода еще ни одну абстракцию не сделало лучше! Копипаста «морозит» код, его крайне сложно менять и поддерживать после тиражирования.
Единственное, что я могу придумать — это маленький тактический выигрыш при явном стратегическом проигрыше. В некоторых ситуациях это хоршая сделка. Наверное.
14. Четко разделяйте ответственность — за каждый участок кода должен отвечать один разработчик
Глупость несусветная. Ушел человек в отпуск — кончилась разработка. Уволился человек из команды — вообще хана, в проекте «черная дыра». Надо уделить больше разработки этому фрагмену — извини, в этом коде только один человек разбирается, не могут пять над ним работать.
Плюс, весь код получается разный, написан в разных стилях, на разных абстракциях, код больше не цельный а напоминает лоскутное одеяло. Что тут хорошего?

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

14. Четко разделяйте ответственность — за каждый участок кода должен отвечать один разработчик

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

94 комментария

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

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

4. Проводите постоянный рефакторинг
Рефакторинг — не самоцель существования проекта, его нужно проводить когда реально назрела необходимость, а не просто потому что кто-то этого захотел или просто все Труъ-программисты так делают. Кстати вы же не забываете перед рефакторингом полностью покрыть функционал Unit-test-ами? Иначе получается не рефакторинг, а «я что-то тут поламаю, может никто не заметит».
6. Тупой, но понятный код всегда лучше гениального, но запутанного
Тупой код — плохо, очень плохо, даже если он понятен. В моей практике это выливалось в перманентное велосипедостроение там где оно не нужно. Когда кому-то лень было прочитать про стандартные логгеры и все «логировалось» System.out.println или например применить AspectJ в спринге, чем оградить себя от большого количества boiler-plate кода. То, что кто-то из разработчиков не знает AspectJ — не оправдание, не знаешь — выучи, но не пиши тупой код.
8. Не пытайтесь продумать архитектуру нового проекта или «фичи» до мелочей перед ее реализацией
Разработчику нужно четко понимать приемочные требования к фиче, что она будет делать, как ее будут тестировать и как она «впишется» в архитектуру. Встречал много непродуманных фич, которые по факту вылились в костыли, которые все боятся трогать.
9. Не бойтесь копипасты
В самом деле, чем вынести все в один модуль/конфиг гораздо веселее искать по коду несколько сотен/тысяч использований, особенно если есть незначительные отличия в реализации и IDE не находит. Вы что серьезно так делаете у себя?
10. Не пытайтесь сильно оптимизировать код до того, как он начнет тормозить IRL
Да, но с другой стороны нельзя допускать ламерский подход, который явно тормозит приложение: коннект к БД без пула, конкатенация String-ов в цикле. Кривая сериализация и прочее. В идеале после каждого спринта есть смысл проходиться профайлером по приложению, в противном случае когда возникнет необходимость вы можете просто не успеть найти узкое место или придется переписывать половину приложения.
11. Не тратьте много времени на highly scalable архитектуру в новых проектах
Не согласен. Лучше разрабатывать проект, предполагающий масштабирование по серверам например с использованием NoSQL БД, чем надеяться, что этого не произойдет. Разумеется пускаться в оптимизации загрузки CSS-ов и хранении их в каком-то CDN есть смысл только когда настанет необходимость, но лучше подстраховать себя.
13. Старайтесь дать всем публичным идентификаторам в коде (модулям, классам, функциям, переменным) разные имена, даже если они принадлежат различным классам/модулям/библиотекам/пакетам
Странный совет, ведь уже давно придумали пакеты, длинна переменной уже может быть больше 8 символов, а классы разумнее называть так, чтобы было понятно что они делают. Причем здесь grep, вы что не пользуетесь IDE?
14. Четко разделяйте ответственность — за каждый участок кода должен отвечать один разработчик
А потом разработчик уходит в отпуск/болеет/увольняется и проект можно закрывать/замораживать на это время. К тому же чаще всего это выливается в то, что другие разработчики не знаю что происходит у них под боком, что не добавляет качества их решениям.

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

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, страницы 21-59.
Особо обратите внимание на итоговую диаграмму взаимодействия после рефакторинга на рисунке 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).

6. Тупой, но понятный код всегда лучше гениального, но запутанного
Да, до тех пор, пока тупой код не будет вызывать связанных с тупостью проблем. Например, performance. Если есть жёсткие требования по перфомансу, то желательно всё-таки не сильно «тупить» код — иначе потом придётся всю эту тупость переписывать. Например, алгоритм поиска в глубину намного тупее и понятнее по реализации, чем тот же A*, но результаты практического применения тупого алгоритма на более-менее больших графах ужасают.
3).
8. Не пытайтесь продумать архитектуру нового проекта или «фичи» до мелочей перед ее реализацией
For agile projects only.
4).
9. Не бойтесь копипасты
Для небольших по объёму автотестов — да. Для больших проектов — спорно. Приводит к огромному количеству переоткрытых багов с пометкой типа «ещё воооот там проявился».
5).
10. Не пытайтесь сильно оптимизировать код до того, как он начнет тормозить IRL
Годится только если нет требований по производительности. Иначе придётся выполнять двойную или даже тройную работу по переписыванию половины проекта более оптимально, а затем по-новой избавляться от функциональных багов (а они появятся, я могу в этом уверить :) )
6).
13. Старайтесь дать всем публичным идентификаторам в коде (модулям, классам, функциям, переменным) разные имена, даже если они принадлежат различным классам/модулям/библиотекам/пакетам
Linux way? Возможно. ИМХО понижает стандартизацию модулей. Мне в той же Идее ничего не мешает отследить пачку идентификаторов в нескольких классах — в отличие от текстового интерфейса греп’а, здесь это гораздо удобнее :)
14. Четко разделяйте ответственность — за каждый участок кода должен отвечать один разработчик
Вот это утверждение самое на мой взгляд спорное. Во-первых, оно идёт вразрез с agile way, по которой прописаны остальные пункты. Во-вторых, приводит к катастрофическим результатам.
Например, разраб уволился — его код никто не знает. Попытка изменить что-либо в таком коде с высокой вероятностью приведёт к получению ещё большей пачки багов.
Далее, приведёт к феномену «незаменимого человека», когда увольнение сотрудника, владеющего некоторой критической частью кода (например, частью ядра), приведёт к фатальным последствиям для проекта, чем данный сотрудник сможет безнаказанно шантажировать контору.
Точно так же приводит к варианту, когда критический баг не будет фикситься до тех пор, пока сотрудник, владеющий данным кодом, не вернётся из отпуска — остальные будут бояться туда залезть, чтобы ненароком не поломать ещё больше.
Например, разраб уволился — его код никто не знает. Попытка изменить что-либо в таком коде с высокой вероятностью приведёт к получению ещё большей пачки багов.
Далее, приведёт к феномену «незаменимого человека», когда увольнение сотрудника, владеющего некоторой критической частью кода (например, частью ядра), приведёт к фатальным последствиям для проекта, чем данный сотрудник сможет безнаказанно шантажировать контору.
Точно так же приводит к варианту, когда критический баг не будет фикситься до тех пор, пока сотрудник, владеющий данным кодом, не вернётся из отпуска — остальные будут бояться туда залезть, чтобы ненароком не поломать ещё больше.

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

Если сторонний разработчик попытается редактировать чужой код, то будет немедленно выявлен и «наказан» хозяином.
В оригинале он звучал так:
Если сторонний разработчик попытается наговнокодить в чужом коде, то будет немедленно выявлен и «наказан» хозяином этого кода.
Это означает, что никто не мешает сторонним разработчикам править чужой код. Но, зная, что у кода есть хозяин, эти разработчики сто раз подумают перед тем, как вставлять туда говнокод. А если они все-таки наговнокодят, то с большой долей вероятности получат «люлей» от хозяина этого кода.
6. Тупой, но понятный код всегда лучше гениального, но запутанного
8. Не пытайтесь продумать архитектуру нового проекта или «фичи» до мелочей перед ее реализацией
9. Не бойтесь копипасты
10. Не пытайтесь сильно оптимизировать код до того, как он начнет тормозить IRL

Напоминает мем хуяк-хуяк :)

Плюну и я в 14.

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

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

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

Со многим согласен.

В п.14 я подразумевал четкое разделение ответственности за код между разработчиками. Это не должно мешать разработчикам изучать «чужой» код и вносить туда свои правки. Читайте ответ Дмитрию Мирошнику выше, чтобы лучше понять мою точку зрения на п.14.

О! Почти техническая статья на DOU! Спасибо!

9. Не бойтесь копипасты
ОМГ, не учите плохому! Копипаста это зло и со злом надо бороться в зародыше. Хороший программист пишет код так, что копипастить не приходится. Тем более, что вы ведь лукавите с
Копипасту в будущем проще свернуть в отдельные функции
т.к. это будущее довольно часто не наступает под внезапным потоком того, что надо делать на вчера.
Лучше выкиньте этот крайне сомнительный «совет» из статьи, пока не поздно.

яросно плюсую. копіпаста це ворог з яким я сильно воюю

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

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

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

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

Советую немного погуглить, прежде чем делать выводы, что означает «небольшой стаж» в данной статье :)

я слабо понимаю зачем что-то гуглить?
написанное в вашем сообщении подтверждает написанное вами же и выделенное мной.

Такие общие советы банальщина и ничем иным быть не могут. Хотелось бы только отметить:

13
Ерунда. И ядро тут совсем ни при чем, т. к. оно написано в ООП стиле, который, при реализации его средствами простого неприплюснутого C, как правило, использует префиксы для имен методов.
14
Несмотря на то, что правило заплевали, считаю его вполне оправданным. Разве что не в такой категоричной форме. Потому шо когда на проекте начинаются все эти игры в «а вдруг автобус-отпуск», «а в модной книге сказали что при скраме все одинаковы и заменямы» и от правила «на каждый кусок — свой ответственный» отказыаются получается «на каждом куске — никого ответственного».
13
Ерунда. И ядро тут совсем ни при чем, т. к. оно написано в ООП стиле, который, при реализации его средствами простого неприплюснутого C, как правило, использует префиксы для имен методов.

Если бы ядро было написано на C++, то грепать его исходники стало бы невозможно, т.к. object_name_function_name() превратилось бы в object_var.function_name() , где function_name() встречается в куче разных классов.

Разговор ни о чем

Главных правила три:
1) Копипаста — самый безошибочный код!
// Только не надо здесь сказывать про «don’t repeat yourself». Зачастую самое глупое что можно делать — это пытаться писать код в одном месте. Вместо того чтобы просто положить 10-20 строк в нужное место копипастой и разорвать гордиев узел зависимостей.
// Да, мне пофиг на лишний килобайт. Но не пофиг на потеряное время в поиске ошибок в чужом коде.

2) Не планируйте масштабирования и универсальности везде. Закон подлости неумолим: это не понадобится там где вы сделали [потратили время]. А понадобится в тех местах, которые вы вообще считали второстепенными. В узких местах!
2а) На незапланированное масштабирование, «по нужде» — будет потрачено намного меньше времени, чем вы потратили на запланированное. Причина проста — видеть легче, чем предвидеть.

3) Не делайте рефакторинг на первом проходе и первых тестах. Отложите его до изменений. Логика здесь элементарна — не создавайте лишний цикл разработки, он даст только убыток. Если код нужный — потребуются изменения и рост качества, тогда и рефакторинг. Если редко пользуемый (особенно одноразовый) — так и напишите в коментах, и не трогайте — львиная доля такого кода устареет.
// Примерно так же писателю книги/статьи не нужно вылизывать свой текст на первом проходе. СНАЧАЛА писать, ПОТОМ — чиркать. Иначе это затянется надолго.

Копипаста — самый безошибочный код!
— тільки варто вставляти в коментах ссилки на цей самий код в інших файлах. Коли його будуть правити/розширювати в майбутньому, зекономиться купа часу.

Можна ще автоматично шукати копіпасту чимось типу такого:
www.getatomiq.com

Не всегда. В большинстве случаев это следует делать только если не понимаешь сам что копипастишь, но «оно же работает». Если же это вполне кошерный кусочек удобочитаемого кода, то почему бы и не слизать?

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

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

Я уже молчу, что банальнейшие вещи типа добавить логирование или оповещение — в чужой код обычно стесняешься. А если это уже твой код — то почему бы и нет? В конце концов, «самтаймс после еды» стоит разобраться как работает то, что ты скопипастил.

Насчет первого пункта а если потом нужно менять логику не возникает проблем?

В этом и суть копипасты. Чего бы ни случилось впоследствие, и кому бы во владение ни ушёл твой код [инициативным джунам], старый код остаётся работать. Но если бы он бы в библиотеке... тут бы посыпался весь карточный домик. Десятки раз с этим сталкивался. И убеждался как опасно делать критически важный код отдельной библиотекой до завершения всех изменений. Зато потом на рефакторинге копипаста заменеяется инжекцией — и вообще никаких проблем!

Хотя каюсь, я сам как-то убил несколько на разруливание бага, оказавшегося примерно в 80 разных местах. А потом ещё столько же на повторное разруливание, когда оказалось что разрулил хреново. Но это был тот случай, когда ошибка не с моей стороны, в в java-машине (это было давно, уже исправили).

Главное в копипасте — иметь ключевую строку по которой её можно найти. Как правило, это... строка с коментом, ГДЕ я это взял. :)

Насчет комента интересная идея

Хотя каюсь, я сам как-то убил несколько на разруливание бага, оказавшегося примерно в 80 разных местах. А потом ещё столько же на повторное разруливание, когда оказалось что разрулил хреново. Но это был тот случай, когда ошибка не с моей стороны, в в java-машине (это было давно, уже исправили).
А не до одного ли места в чем была ошибка? Вам тогда понравилось делать массовую замену во всех этих местах? А кол-во строк и мучения тех, кто будут этот код меня... а хотя, зачем я это все спрашиваю, действительно. После
Главное в копипасте — иметь ключевую строку по которой её можно найти.
меня не покидает мысль, что вас уже не исправить...

Якщо потреба міняти логіку виникає в двох кусках, тоді код зводитсья назад, в одну функцію.

З мого досвіду, копіпаст виправданий, якщо без нього доводиться порушувати зв’язки\необхідно багато часу на рефакторинг.

Якщо вам потрібно зкопіпасти те саме ще раз\поміняти логіку в двох шматках, тоді вже зводити в одну функцію.

Класичний приклад: Є модуль А з внутрішнім функціоналом A.a, є модуль Б, якому теж потрібен A.a.

Варіанти рішень:
1. Зробити А.а публічним, щоб Б мав доступ до А.а
2. Винести А.а в С, зробити С.а публічним, щоб А і Б мали доступ до С.а
3. Скопіпастити А.а в Б.а

В мому досвіді, часто було таке — виносиш в С.а, тратиш час, а через дві неділі задачі міняютсья так, що Б потрібен модифікований А.а -> А.а’, а А потрібен той самий А.а і виходить, що потрібно все повернути назад (або залишити мертвий код С.а) і написати Б.б.

Тут зачароване коло, коли ви досягаєте одного, втрачаєте інше :)

Висока ізоляція модулів — є або мертвий код, або копіпаст
Немає копіпаста — низька ізоляція модулів або мертвий код
Немає мертвого коду — є або копіпаст або низька ізоляція модулів

Висока ізоляція модулів, немає мертвого коду, немає копіпаста — думаю, що нікого не влаштує час виконання задач.

Звичайно, це все не стосується добре детирмінованих проектів, коли програмувальник отримує 98% ТЗ. Це стосується тривіальних ринкових проектів, коли замовник міняє\додає задачі кожні дві неділі.

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

Ні. Це, скоріше має бути винятком. Причому документованим, де ви взяли і чому.

Просто правило «не копіпасть» так жорстко просувається, що іноді люди тратять пару днів і пишуть багато додаткового коду, там де «копіпаст» в принципі, допустимий.

Думаю правило мало б бути таке: «Не копіпасть! але якщо дуже треба, то можна, закоментувавши чому саме це треба» :).

1) Копипаста — самый безошибочный код!
Бред. Копипаста кода с багой — это клонирование баги, как правило.

Код который идёт на копипасту как правило старше того, в который. Следовательно, допустить ошибку при самостоятельном написании в десятки раз больше, чем взяв зрелый.

Учи мат.часть!

Код который идёт на копипасту как правило старше того, в который. Следовательно, допустить ошибку при самостоятельном написании в десятки раз больше, чем взяв зрелый.
Ну и где тут логика вообще? Тот кто писал старый код, по-вашему, как правило гуру программинга? Или на чем основывается ваша вера в непогрешимость «старшего кода», который копируется? А между прочим, нередко бывает, что копипастеры копируют свеженаписанный код в рамках одной той же задачи или серии задач. И термин «зрелость» в таких случаях не подходящий.
Учи мат.часть!
Лол, какую мат.часть? На кого ссылаетесь хоть?

А еще прикольнее зависимость копипаста порождает, если копипастить код без багов. Это скрывание будущих багов ))

Повторения кода — это злейшее зло, не понимаю, о чем здесь спорите все ))

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

не понимаю, о чем здесь спорите все ))
Та вот нельзя так просто взять и спокойно смотреть, как перевираются общепризнанные истины (что копипаста это зло, например) по принципу «2+2 не 4! 2+2 на самом деле 5, а до этого вам врали!» Вот потому и спорим) Увы, в наш век, часто так бывает — много кто(мечтая войти в история революционером, наверно) дерзит пошатнуть основы мироздания, пойти против системы, перевернуть сознание, etc.
Вылизивать на каждом шаге код, стараясь его минимизировать — хорошее упражнение для ума, но с точки зрения производительности программиста не всегда оправданное.
Я предпочитаю этот вариант, при малейшей возможности. Он, конечно, сложнее, но избавляет от необходимости следить за копипастой и успевать её чистить. Эдакая антипрокрастинация) Плюс, держит мозг в тонусе)

Да, это я фразой

Главное, производить эту чистку время от времени
слишком теоретизировал. Как в анекдоте:
— Пью я только когда ем борщ. А борщ я ем каждый день.
Чистка как минимум должна быть перед комитом. А по поводу копипасты, не могу вспомнить серьезных причин ее делать. Да, я делаю копипасту не особо задумываясь. Но только чтобы быстро тесты прошли, чтобы после этого глянуть со стороны на код и понять, как лучше вынести код в отдельный метод.
А по поводу копипасты, не могу вспомнить серьезных причин ее делать
Там только одна причина может быть (имхо) — скорость кодирования (и то, иногда пункт оказывается спорным)
Копипасту имеет смысл использовать разве что в каких-то одноразовых скриптах (т.е. которые без претензий на поддержку)
Да, я делаю копипасту не особо задумываясь. Но только чтобы быстро тесты прошли, чтобы после этого глянуть со стороны на код и понять, как лучше вынести код в отдельный метод.
Ну, если при этом чистка перед комитом возведена на уровень рефлексов, то все ок)
Там только одна причина может быть (имхо) — скорость кодирования (и то, иногда пункт оказывается спорным)
всегда кажется спорным. Если что-то скопировали более двух раз, то далее выделение мышкой кода, Ctrl+C Ctrl+V — занимает как бы больше времени, чем набрать имя метода.

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

В общем, копипаста — это всегда плохо. То, что пишет Алексей Пение по поводу разрыва зависимостей... Даже не знаю, какую задачу он в это время представляет. Если что-то повторяется, то оно и по смыслу «одно и то же». Если есть смысловая зависимость, то она ДОЛЖНА выражаться и в коде. Мы ж пишем код не просто ради кода, не просто желая сделать абсолютно гибкое ничто.
Если в какой-то момент требуется от того метода другое поведение в другом месте, пишете другой метод и разрывается зависимость легко.

Кстати, думаю, про зависимости — это тоже связано с психологией и пунктом 14. Я встречал такой антипаттерн не раз. Не знаю, как он называется. Жадность, наверное. Когда человек прежде чем начать работать, копирует всё себе. Например, всегда дублирует данные, заводит бессмысленные переменные, на которые завязывает весь код.
А тут: взять и скопировать из чужого кода кусок, а потом не быть зависимым от того, как дальше будут менять тот кусок. Разработка во вражеском окружении

Хм, интересная гипотеза. Что-то в этом есть.

Поправте URL. Advice всегда множественное число, и не может быть advices.

Нифига. Нативная природа языка берёт своё, и народ его склоняет вопреки исключениям грамматики.
Ближе всего к его смыслу даже не «советы», а «премудрости». Мудрость множественным числом не сделаешь, а премудрости — аж бегом.

Вам виднее, пан филолог! Но, увы, классический английский он таков.

Причём тут «филолог», просто пообщайся с реальными людьми, и когда встретитшь хоть раз слово «advice» со смыслом множественного числа и не в форме advices — свистни. Юридические и старые тексты не в счёт, желательно пользовательский контент.

Пойми одну мелочь — раньше письменные издания жёстко редактировались, и это повзоляло грамматике жить «по правилам». Сейчас львиная доля контента не редактируется, и это приводит к упрощению языка. Исключения выпиливаются. Тем более исключения которые за каким-то хреном тянутся ещё со времён латыни.

Ты же не говоришь «чипы» или «чипс», а говоришь «чипсы». Хотя это и неверно с точки зрения грамматики.

Всё что хочу сказать — не стоит быть в наше время grammar nazi. Языки меняются в сторону упрощения, и глупо объяснять что-то большинству. Которое изъясняется как им удобнее. Глядишь, лет через 30 и неправильные глаголы выпилят, оставив максимум десяток. Лично я это уже наблюдаю сплошь и рядом.

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

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

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

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

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

1. Пишите только тот код, который вам действительно необходим в данный момент
Так, вероятно, можно получить фичу быстрее. Но — придется переписывать код потом каждый раз, когда прилетают изменения. Причем не только по функционалу — а еще и по другим фичам, которые в той или иной степени касаются этого кода.
Таким образом, если пытаться заглянуть в очень далекое будущее — решение будет слишком сложным. Если не видеть дальше своего носа — слишком простым. Очевидно, где-то между этими значениями функция достигает максимума. Где бы?
3. Начинайте новый проект с минимального набора функциональности
Звучит круто, но как же понять, какой набор — минимальный? Джобс, например, придерживался обратного принципа, выпускал продукты только достигшие эффектного состояния — и немало преуспел. Может не все так просто, может есть и альтернативы?
4. Проводите постоянный рефакторинг
Постоянный рефакторинг = постоянные затраты времени девелоперов не приносящее никакой новой функциональности. Возможно, еще и потому, что многое было сделано «с минимальным набором фич» и «настолько просто, насколько возможно». Может, это не принцип, а неспособность предвидеть на минимально внятное время? Предполагаю, что если экстремально увлечься идеями YAGNI, KISS и MVP можно с определенного момента времени тратить вообще все время только на рефакторинг.
5. Предпочитайте простые решения сложным
От простого до убогого — один шаг. Как понять, что он не сделан? Все должно быть сделано насколько просто, насколько возможно, но не проще!
6. Тупой, но понятный код всегда лучше гениального, но запутанного
Я бы поостерегся использовать слово «всегда». Не говоря уже о странной пресуппозиции того, что «тупой» может быть «понятным» в то время как «гениальный» является «запутанным».
Я бы понял, если бы совет звучал как, например «читаемость кода важнее его производительности». А так — теряюсь в догадках. Кроме того, тут тоже надо понимать, когда остановиться.
7. Не загромождайте проект ненужными абстракциями в виде промежуточных API, фреймворков, классов и интерфейсов
Как же понять, какая абстракция — ненужная? «Если абстракция существенно усложняет отладку кода, то быстрее выпиливайте ее из проекта.» — а если при этом добавляет суперфичу на весь проект? У нас цель-то конечная какая? «Если новичкам на проекте приходится тратить более недели на изучение правильного использования, слишком заумной абстракции, то стоит подумать над ее упрощением или полным отказом от нее» — стоило об этом подумать, когда вы ее писали. Раз уж написали — наверное, для этого были причины. Является ли неделя новичка более весомой причиной? Сомневаюсь.
Любой новый фреймворк вызывает недели и месяцы изучения у любого программиста — значит ли это, что он — ненужная абстакция?
8. Не пытайтесь продумать архитектуру нового проекта или «фичи» до мелочей перед ее реализацией
Вы уже дали этот совет под номером один — проблема та же. Думать слишком мало — плохо, думать слишком много — плохо, сколько в самый раз — непонятно. То, что не надо бросаться в крайности — это не новость. Лучше расскажите, как попасть в самую мякотку.
9. Не бойтесь копипасты
Бойтесь копипасты! Копирование кода еще ни одну абстракцию не сделало лучше! Копипаста «морозит» код, его крайне сложно менять и поддерживать после тиражирования.
Единственное, что я могу придумать — это маленький тактический выигрыш при явном стратегическом проигрыше. В некоторых ситуациях это хоршая сделка. Наверное.
14. Четко разделяйте ответственность — за каждый участок кода должен отвечать один разработчик
Глупость несусветная. Ушел человек в отпуск — кончилась разработка. Уволился человек из команды — вообще хана, в проекте «черная дыра». Надо уделить больше разработки этому фрагмену — извини, в этом коде только один человек разбирается, не могут пять над ним работать.
Плюс, весь код получается разный, написан в разных стилях, на разных абстракциях, код больше не цельный а напоминает лоскутное одеяло. Что тут хорошего?

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

От простого до убогого — один шаг. Как понять, что он не сделан?
В мемориз.

Хорошо написано.

Добавлю пару комментариев:

Любой новый фреймворк вызывает недели и месяцы изучения у любого программиста — значит ли это, что он — ненужная абстакция?
В большинстве случаев — да. Тут недавно проскакивала классная картинка на эту тему — pbs.twimg.com/...EveIcAEsTqH.png .
Глупость несусветная. Ушел человек в отпуск — кончилась разработка. Уволился человек из команды — вообще хана, в проекте «черная дыра». Надо уделить больше разработки этому фрагмену — извини, в этом коде только один человек разбирается, не могут пять над ним работать.
Плюс, весь код получается разный, написан в разных стилях, на разных абстракциях, код больше не цельный а напоминает лоскутное одеяло. Что тут хорошего?

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

Проблемы разных стилей решаются с помощью соблюдения coding style guides, принятых на проекте.

14. Четко разделяйте ответственность — за каждый участок кода должен отвечать один разработчик

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

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

Он знает возможные проблемы и их решения, что и для чего можно использовать

Тести показывают проблемы и как они решаются через код. Как это будет работать и реализовано решает команда, а не один человек (планирование «скоупа» работ и реализация). Ответственность несут тоже все. Написание контролируется тоже командой (code review, switch pairs and context). Нет hero-mode, он просто не нужен.

Тести показывают проблемы и как они решаются через код
К сожалению, тесты не показывают проблемы структуры .
Ответственность несут тоже все
Как? Нет, мне правда интересно, как ответственность могут нести два и более человека. Методом децимации?

Методом — про**ал один, недосмотрели — все. Один писал, другой сидел в паре, третий ревьюил результат.

Так какие последствия для «всех»? Оставить без полдника?

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

ок, вот пример «из жизни»: В результате копрокода, название метода не соответствовало тому, что он реально делает. Программист использовал этот метод и в результате отписка от писем перестала работать. Итог — почта пошла в спам.

Итак, в вашем случае, что нужно было сделать с командой? (100+ человек)

Да не наказываю я. Я нахожусь с другой барикады. Данный подход пока не позволил допускать такие проблемы.

ЗЫ даже если проект большой — команды дробятся на 4-5 человек, так что будут отвечать 4-5, а не 100 (точнее 4-5 + пару кто ревьюил)

Данный подход пока не позволил допускать такие проблемы.
Закон Мерфи — то что может случиться, рано или поздно случится. Я обожаю тим-ревью, но даже с таким подходом, на одном из проектов пролетела бага, которая убила регистрацию(!)

Как бы там ни было, но вы заявили, что отвечает вся команда (6-7 человек, с ваших же слов). Вот мне и интересно — а каким, собственно говоря, образом? Или это просто красивое слово?

Я обожаю тим-ревью, но даже с таким подходом, на одном из проектов пролетела бага, которая убила регистрацию(!)

А тесты на регистрацию не?

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

Но это не важно. Вопрос в том, какие должны быть последствия?

Без понятия. Можете в подвале закрыть и паяльником мучать. Или всю ЗП на нужды АТО перевести :)

це якась зграя студентів :)

человек может заболеть/уйти в отпуск/уволится. Тогда он становится узким местом в разработке

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

Как это будет работать и реализовано решает команда, а не один человек

Ілюзія, для підняття командного духу. Зазвичай 90% пропонує одна людина, що найкраще розбирається в області, а всі інші просто погоджуються.

Ще одна форма, коли питання виноситься ПМом, обговорюється і «затверджуєтсья» командою, і якщо воно збігаєтсья з рішенням, прийнятим ПМом, то говориться, що рішення прийняла команда, якщо не збігаєтсья, то приймається те рішення, яке прийняв ПМ. Замість ПМа можна підставити архітектора чи продакт овнера.

Вы можете говорить, что так не возможно. Но мы так работаем без ПМ-ов/архитекторов/прочего бесполезного персонала (игра в испорченый телефон с продакт овнером у нас не работает) в командах. Решение принимаются всеми, если один будет не согласен — он потом будет не доволен процессом разработки. Зачем создавать такие проблемы?

Цілком вірю, «без ПМ-ов/архитекторов/прочего» — загальний тренд, на моєму проекті теж.

Я про те, що у вашій команді все одно є центри впливу з певних питань.

Говорити про загальний одобрямс в команді з 10 чоловік — не вірю, завжди будуть ті хто проти, мають альтернативну думку, але вони просто погоджуються, щоб не конфліктувати.

Якщо є двоє активних з протилежною думкою — явний конфлікт в колективі. Без «авторитета», який може прийняти кінцеве рішення, і якого послухають всі, команда швидко зруйнується.

центр влияния — продакт овнер (что логично, он платит деньги). Остальные разработчики/дизайнеры равны, будь то со стажем 10 лет или всего год. Люди и их взаимодействия важнее процессов и инструментов.

Лёша, раскажи пожалуйста, как вы обрабатываете ситуацию, когда из команды, допустим в 5 человек 1 — не согласен (категорически и по техническому решению), а выкатить функционал то все таки нужно? При этом не задеть чувств несогласного и/или согласных.

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

Зависит от аргументации. Нужно понять почему он не согласен, в то время как остальные согласны (это его участок кода? он знает то, о чем остальные не в курсе? а может эти 4 человека знаю то, что 5 не в курсе, и риски намного меньше, чем он себе представляет?)

По моему опыту, технические проблемы решаются в команде достаточно просто. Некоторые идут на уступки в одном (например в выборе платформы разработки), но не дают уступок в другом (покрытие тестов не менее 95%).

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

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

У нас в одном из проектов такая роль называлась Component Guardian: следил за тем чтобы другие туда фигню всякую не коммитили, на вопросы отвечал. Жалоб на такой подход не наблюдалось.

ИМХО, кроме этого, один ответственный должен быть на каждую составную задачу, если задача содержит связанные участки, закрепленные за другими разработчиками, все равно остается один главный ответственный за основную задачу, контролирующий процесс выполняния задач на связанных участках. Иначе может возникнуть управленческая проблема для таких, «распределенных по коду», задач: первый сделал свой участок, перебросил задачу на следующего и умыл руки.

См. мои комментарии выше на аналогичные возражения

Я так и не увидел пункт по TDD/BDD/*DD. Тесты где? Программист может писать какой угодно код — тесты должны рассказать как он должен работать правильно + я вообще не представляю рефакторинг без них (это как бегать по минному полю) :)

Ну как же?! Тесты это никогда не нужный код. Он же не реализует ТЗ.

Он входит в ТЗ. Например в TDD реализация любой фичи начинается с тестов.

Он просто является переводом ТЗ :)

Про тесты планирую написать отдельную статью.

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

8. Не пытайтесь продумать архитектуру нового проекта или «фичи» до мелочей перед ее реализацией
Очень абстрактно. К примеру на начальных этапах впилить многоязычность куда проще чем уже на прод серваке в котором эта самая многоязчность не подразумевалась изночально это типичный пример который попадается в книгах. Другой пример это проектирование API тут желательно подумать о формате передачи данных и том, как должна вести себя система при не валидных запросах в каком формате должен приходить запрос и в каком виде отдаваться результат.

Вышеописанные советы давались для разработки application кода, а не библиотечного кода. Как вы правильно заметили, для библиотечного кода некоторые советы, включая п.8, не годятся.

Если сторонний разработчик попытается редактировать чужой код, то будет немедленно выявлен и «наказан» хозяином.
А потом хоп и чувак уволился, лезут в его код — а там адъ и израиль.

Ответственность и владение кодом — разные вещи

А как же open source? Там постоянно лезут с pull requestами и даже рады оному.

Так а в опенсорсе никто и не орет «не лезь в мой код» ))

Похоже совет #14 получается самым противоречивым.
Добавлю ещё кое-что к нему: как минимум необходимо код-ревью, что если вдруг вашего разработчика-специалиста своего участка переедет автобус?

По поводу 14-го пункта.
Данный «best-practice» нашёл применение в моём проекте. Надо будет через месяц с тролл-фейсом спросить ребят как там дела с моим кодом :)

На счет № 14 — не совсем согласен. Не лучше ли внедрить практику код ревью и иметь минимум двух человек, которые понимают данный участок кода и несут за него ответственность ? От пинг-понга это также избавляет, т.к. появляется командная игра и взаимопомощь. (потому что люди начинают понимать что даже если сейчас это не их код, то завтра им возможно придется это ревьюить и принмать ответственность)
Ну а за наказания про редактирование «чужого» кода — это по-моему уже вообще за гранью... так вы никогда ничего не отрефакторите. А если кто-нить в отпуск уходит — так это вообще форс-мажор получается ;)

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

«Чел, дык это у тебя с командой что-то не так и общий-значит-ничей код это не лучше а может и хуже» — скажут некоторые. Спорить не буду. Но выдавать одну крайность как «хорошо», только потому-что другая — это «плохо» — это неправильно.

п.с. я работал в проектах где применялось и то и другое. Сode sharing показывал себя лучше чем specialization.

Статья ок, всё хорошо, но пункт N9... как бы мягче сказать... :)

«...Наконец, попадаются и дураки решающие проблемы. Они не задумываясь делают глупости, которые кому-то потом приходится разгребать. Это делает их должниками компании, так как они не только не вносят своего вклада, но и тратят время умных людей. К этому типу относятся любители копировать большие куски кода вместо создания подпрограмм, поскольку это хотя и по-дурацки, но работает»
(Joel Spolsky)

Подписаться на комментарии