Как я решил проблему плохого кода с помощью architecture guide

Всем привет!

Буквально на днях, спустя три недели после выхода на работу, мой новый программист пишет такой же код, как и трое моих других опытных разработчиков, которые на том же проекте около года.  В свою очередь эти трое создают единую архитектуру, дают одинаковые названия сущностям и пишут чистый код, что сильно упрощает проведение code review и облегчает всем понимание кода.

В этой статье я поделюсь своим опытом : за счет чего же я этого достиг. Я думаю мой опыт может быть вами  применен в любой сфере IT и не только!

Синдром утенка

Давным давно, на заре своей IT карьеры, порядка 10 лет назад, я был на должности руководителя группы отдела технической поддержки. В мои обязанности входило обеспечение техподдержки клиентов компании.  Нужно было принимать звонки и помогать клиентам. У нас в отделе было 2 группы. Одной управлял я, другой мой коллега. В каждой группе было где-то 8 — 10 человек. На тот момент мы оба были без опыта обучения и управления людьми, мы были из бывших сотрудников поддержки. Мы хорошо знали как все работает с технической точки зрения, но опыта  управления у нас не было. Соответственно нам никто ничего не объяснял, ничему не учил и не передавал опыт.  Как следствие мы управляли своим персоналом по наитию и по большому счету делали все то же самое, что делал с нами наш предыдущий «босс», когда мы были обычными инженерами. Так сказать в полной мере воплощали «синдром утенка», повторяли все за ним. Естественно, новых сотрудников нужно было обучать. И следуя синдрому утенка, мы оба, как и наш предыдущий босс, когда всего было 6 человек в отделе, обучали своих подчиненных лично. Садились рядышком с обучаемым на стульчик и объясняли: «вот смотри, тут у нас …».  И в таком режиме обучение проходило пара рабочих дней. Мне кажется, что мы таким образом обучали абсолютно всех инженеров около двух лет. За эти два года я даже умудрился расписать 2 листа А4, с порядка 40 вопросами, которые нужно успеть обсудить с учеником за эти 2 дня. И все бы наверное так и шло своим чередом, пока где-то спустя 2 года, один из моих инженеров подрос профессионально и в один прекрасный летний день спросил у меня: «А зачем ты им постоянно объясняешь одно и то же? Не легче ли описать мануал с типовыми вопросами и дать им читать, а потом что непонятно проговорить лично?». Я не доверительно отнесся к его словам, ведь разве люди способны сами понять такую «сложную» тему как протокол sip или работу с wireshark? Я был просто уверен что однозначно — нет. Но парень вызвался написать данный мануал сам и проконтролировать результаты с обучаемым, я согласился.

Правило Паретто.

Через 3 дня он мне прислал первый мануал по wireshark, с картинками и описаниями всех основных команд которыми мы пользовались и как в нем анализировать sip, rtp трафик и т.д. Я рискнул, дал одному из новых сотрудников изучить работы с wireshark по данному мануалу. Затем они созвонились с обучаемым, и с час что-то обсуждали. После этого я стал проверять знания новичка. И вы знаете, мне понравилось.  Новичок действительно с помощью данного мануала  усвоил и применял на практике все основные, типовые моменты где-то 80%. Остальные 20% он узнавал от меня, либо при работе с коллегами или в интернете. То есть я на практике видел работу закона Паретто, 20% усилий (проговорить основные моменты в работе) дают 80% результата. Убедившись в эффективности прокачки людей по гайдам, я перестал их обучать по wireshark вообще, стал давать читать только данный мануал. 

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

После нескольких успешных обучений wireshark только по гайду, я стал размышлять на тему как так вышло, что я учил сотрудников 2 года лично, тратил на них свое время, силы, повышал на них голос, иногда грубил. Мне казалось что они сами не были способны изучить те темы, которым я их учил и единственный носитель истинности и правды это был — я сам, именно вследствии этого  у меня было явное недоверие к тому, чтобы они обучались сами. Но как показала практика, они без меня , сами, прекрасно и спокойно обучились основным моментам, на которые уходило 80% времени. Как так? И тут мне пришла гениальная мысль «А если человек умеет читать, то возможно он способен понять что написано?», тем более мы целенаправленно брали на работу только людей с высшим образованием. А что еще студенты делают, как не читают книги и изучают их, а тем более делают это на результат, чтобы получить оценку? И тут меня осенило: оказывается, люди с высшим образованием способны прочитать материал и понять его.

Масштабирование.

Как только я это осознал,   я сразу понял, что подобные гайды просто необходимо масштабировать по другим  темам, которым я учил. Я написал порядка еще 7 гайдов, и сложил их в одну папку с говорящим названием «Система обучения». В итоге у меня так впервые за 2 года моей «управленческой карьеры» появилась папка, в которой были собраны основные моменты в работе.

Делегирование

Мне понравился  тот момент , что новичок прокачался без моего участия, а также то, что его знания проверял не я. Я предположил , что данному опытному сотруднику было несложно обучить новичка, т.к новичок перед этим прочитал его гайд. Спустя месяц — два я решил опробовать данный эксперимент с другим опытным инженером. Объяснил ему ситуацию , показал гайд, и поставил задачу обучить очередного новичка wireshark. Особого негатива я у него не увидел, наверное потому-что задача была поставлена в четких рамках, уже был составлен мануал, и нужно было проверить , что человек его прочитал.  Результат был такой же, как и в первый раз. И тут меня осенило: оказывается, не обязательно учить людей самому, а можно это делегировать. А для того чтобы у «учителя» не было «молчаливого отрицания», всего-то нужно ему предоставить  уже готовый материал и замотивировать. Мне это так понравилось, что я поставил это дело на поток. Теперь за обучение в моей группе отвечал самый опытный инженер, и я практически перестал заниматься этим лично.

Передача опыта.

Время шло, количество сервисов компании увеличивалось, как следствие увеличивалось и количество гайдов. В папке стало лежать порядка  20 гайдов. Новым сотрудникам сложно было понять в какой последовательности что читать. Я стал группировать имеющийся материал по темам, также я смотрел сколько времени в среднем уходит на обучение той или иной темы и стал указывать это время в данном файле. Через некоторое время к нам в компанию пришел «бизнес тренер», который поделился со мной программой для обучения. В ней можно было составлять тесты и назначать их сотрудникам. Я стал пользоваться этим инструментом. В итоге у меня была теоретическая часть, практическая часть, проверка знаний с помощью тестов. В сумме на все первичное обучение требовалось порядка 10 рабочих дней. Оцифровка опыта облегчила мне  его передачу между инженерами.  С приходом нового инженера я давал ему гайды и через некоторое время он плюс — минус начинал обладать теми же знаниями, что и более опытные сотрудники. Также это делает возможным передачу в случае ухода из компании  сотрудника, который был источником знаний. Я просил самых опытных ребят проводить редакцию гайдов. Они делали дополнения, и в итоге основной их опыт оставался в компании.

Что в итоге

В итоге, через 4 года  у меня была составлена система обучения инженера по первые 6 месяцев работы. Там были материалы на 2 недели, 1 месяц, 3 месяца, 6 месяцев. Чем больше инженер работал , тем более сложным становился материал. Все было описано в одном файле, с четкой градацией по темам и дня работы инженера. При выходе инженера ему автоматически назначались тесты. Отчеты по тестам приходили мне. Обучением занимались самые опытные инженеры, у них для этого был пункт в их системе мотивации.  Моего времени на прокачку стало уходить существенно меньше, посчитайте сами, у меня было где-то 9 инженеров со средним сроком работы 22 месяца. 22 / 9 = 2,4. То есть каждые 2.4 месяца мне раньше приходилось с нуля обучать людей, на протяжении нескольких дней — недель.

В итоге система обучения дала:

1) Освободило меня от обучения: я стал тратить больше времени на выстраивание других процессов и работу с персоналом. 

2) Предоставило бизнесу четкие сроки и критерии качества обучения новых сотрудников

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

4) Делала обучения всех инженеров единым, т.к у них был один источник знаний.

Переход в разработку.

Время шло, я стал заниматься разработкой софта для техподдержки и клиентов компании. Для своих разработчиков я никаких гайдов не составлял т.к ни я, ни они не понимали как правильно работать в том или ином фреймворке. Где-то через 3 года я прокачался как fullstack angular + node.js, и меня пригласили лидом на angular. Моя основная задача была — поднять качество разработки у разработчиков и сформировать архитектуру проекта. На проекте было 2 разработчика , еще 1-ого нужно было нанять. Когда я посмотрел на проект, то увидел кучу проблем, такие как:

1) Названия у сущностей не отображало их назначение

2) Отсутствие типизации, 60% кода было с any). Т.к DTO бекенда генерировались через сваггер, это конечно было круто, но благодаря великому и могучему any эти DTOшки моментально расправлялись ни во что. 

3) некорректная работа с rxjs (  отсутствие отписок, вложенные подписки, подписки в changes,  так где должен был быть 1 эмит было тысячи и наоборот)

4) нарушение правил работы с фреймворком.

5) отсутствие архитектуры, несмотря на то, что ангуляр , как и любой другой фреймворк, отчасти диктует правила «игры», но все равно остается куча мест, в которых можно поступить по-разному. И эти два разработчика так и делали — каждый раз поступали по разному.

6) при работе  с массивами вместо .map .find .foreach  и т. везде был for (…)

7) Повторение за «другими». Проекту было уже 4 года и в нем работали все подряд,   в результате эти программисты просто копировали старые решения, хотя они были в корне не верные.

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

SMART

Все творчество вверенных мне программистов конечно было милым, но явно не тянуло до корпоративного уровня. В нем нужно было что-то менять. Самый простой вариант: собрать всех и сказать, или что ближе к моей манере «наорать!» :   «Ребята давайте кодить нормально» — не сработал бы, просто в труху. Я прекрасно это знал по моему опыту в поддержке. И я стал применять наработанный мною подход постановки задачи по SMART. А именно

  1. S однозначное понимание: все ребята должны были также как и я 1×1 понимать как выглядит «качественный код» в моем понимании

  2. M измеряемая: ребята должны понимать, как именно я замеряю качество их кода, критерии оценки должны быть простыми для понимания и не иметь двояких трактовок

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

  4. R реальная : качественный код должен быть ими реально сделан

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

Цикл Шухарта–Деминга или PDCA

Было понятно, что нужен единый источник знаний. Я стал искать в интернете гайд «как лучше писать проект на angular» , «angular best practices», но нигде ничего не находил. Были разрозненные статьи на тему того, как поступать в той или иной ситуации, но так, чтобы был единый гайд, в котором был бы «оцифрован» весь лучший опыт, а именно — расписан алгоритм построения монолита с указанием неймингов, структурирования папок, работой с rxjs, работой с фреймворком просто не было. Поэтому я стал формировать этот гайд сам.Когда я начинал создавать гайд, у меня не было чувства страха и, как результат я не испытывал чувство прокрастинации , т.к еще при создании системы обучения саппорта я на своей шкуре работу цикла PDCA (планируй, делай, контролируй, корректируй) и понимал как эта штука работает. Суть цикла простая — любую процессную деятельность нужно периодически  контролировать и корректировать. В результате этого, а именно после корректировки, деятельность начнет расти. И что самое главное, так это то, что заранее не нужно знать как правильно или не правильно поступать, достаточно начать. Важно как можно проще подойти к PLAN, DO и сделать их. PLAN у меня уже был, кидать в txt файлик кривой код. Осталось только начать, перейти к DO.

Как я сделал свой первый Do

Первым дело я создал на рабочем столе txt файлик))))) — «Новый документ» и стал в него вносить ошибки в коде, которые я явно видел. 

1) В нем я стал помечать ошибки в коде. Каждый раз когда я проводил code review одного из программистов, я помечал в коде участок кривого кода фразой.  »// TODO CR Описание ошибки.». Стоит отметить, что у нас были «ошибки» двух типов: обязательные и вкусовщина. По обязательным решение принимал я, за мной было последнее слово. Мы вместе обсуждали проблемные зоны, но конечное решение было за мной. Когда я не знал, как поступать в той или иной ситуации, я начинал исследовать проблему. Спрашивал у более опытных коллег в чатах, искал в интернете, воспроизводил проблемы в тестовом проекте. Когда я находил решение, я собирал ребят, показывал им решение и они обязывались его соблюдать в разработке, а я при code review. При вкусовщине мы принимали решение по большенству: как большинство решило , так мы и поступали.  

2) Затем я собрал ребят и объяснил им, как я буду проводить code review, например, как помечаю ошибки в коде, а они обязаны до релиза их исправить. (это можно еще  делать в merge request, но было удобней так)

3) Я настроил фильтр TODO в своей IDE и показал ребятам как его настроить у них, чтобы он попадал в глаза. Стало выглядеть так.

c541e5e0aad02ecc8137b378eae21524.png

Каждый раз когда я видел новую ошибку в коде, я ее полностью вставлял ее в текстовый документ, например:  

df5a9167a141131b0e63a0d9103a31c7.png

4) Раз в неделю мы собирались с ребятами и обсуждали с ними каждый кейс из моего файлика, то есть я занимался их прокачкой на базе реального примера из проекта. Я говорил, как нужно делать, как не нужно и почему мы все договариваемся, как поступаем в тех или иных случаях.

5) Иногда мы принимали одно решение, но в процессе работы кто-то показывал, что оно не работает, находил новые кейсы или читал статью, что так нельзя делать, в итоге мы это решение переписывали и так больше не делали (реализация CA из PDCA)

5) Я не всегда успевал скопировать пример «кривого» кода в файлик и тут мне на подмогу приходили коммиты, Каждый раз при указании тудухи я делал коммитит по одному и тому же шаблону «Номер таски Название таски Add TODO CR» и пушил коммит в бранч. В итоге в поиске  коммитов по слову «Add TODO CR» я всегда мог найти и просмотреть не учтенные мною коммиты, добавить их в файлик и потом обучить по ним ребят.  В принципе это все можно делать и в merge request  в вашей git системе, но мне было удобней так.

6) Для того чтобы ребята не держали правила в голове и они были всегда под глазами, я перенес все данные из файлика с моего рабочего стола в «README.md» git репозитория и дал ссылку на него ребятам. В итоге у них появился единый источник знаний , на который мы все обязаны были равняться.  Если какая-то наша договоренность становилась неактуальной, я всех собирал, и мы обсуждали новое правило, естественно, как следстви редактировали гайд. Таким образом , гайд всегда был в актуальном состоянии.

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

8) Настроили интеграционные тесты Cypress и встроили их в CI

9) Правила мы составляли не только для кода, но и для тестов

10) Под часть правил мы стали настраивать линтеры и также их встроили в CI

Результаты

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

В итоге гайд дал результаты, аналогичные тем, которым я получил в техподдержке, а именно:

  • я потратил минимум своего времени на обучение нового программиста

  • все мои программисты обладали одинаковыми знаниями и одинаково применяли его на практике

  • было легко контролировать время первичного обучения, как и его результат на выходе, с помощью проверочного задания

  • поднятие психологического климата в коллективе, т.к каждый знал, что сосед пишет такой же «качественный» код как и он сам.

  • облегчило работу с возражениями при постановке задачи на доработку, багфикс чужого кода.

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

Кому нужны гайды

Я считаю, что подобного рода гайды нужны, если у вас в подчинении 3 и более сотрудников и для вас важна долгосрочная поддержка проекта. В этом случае вы уменьшаете себе время на обучение сотрудников, так если у вас 3 сотрудника со средним временем жизни 24 месяца, то вы будете обучать нового каждые  8 месяцев  + время на его поиск. Я думаю, что на обучение и поиск вы будете минимум тратить 1 месяц. Так что если вы аутсорс с более чем 20+ разработчиков на одном фреймворке, то где ваши гайды? Вынесите их в open source, где вы можете получить обратную связь для их улучшений. 

Также в гайде или базе знаний остается весь опыт вашего лида, что очень выгодно бизнесу. Т.к в случае ухода лида из компании весь его опыт остается внутри компании. Так же это развязывает руки при найме сотрудников, т.к когда у вас есть база знаний , вы можете брать сотрудника на уровень ниже на все позиции  Junior, Middle, Senior, Lead. Главное чтобы у кандидата было желание обучаться, остальному он научится сам по гайдам. Я считаю, что это особенно важно для аутсорс компаний, для которых критично нанимать слабых разработчиков, а выдавать за сильных. С гайдами их слабые разрабы через 3–4 месяца работы сильно вырастут.

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

Примеры гайдов

А где ваш гайд?

© Habrahabr.ru