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

GuDron

dumpz.ws
Admin
Регистрация
28 Янв 2020
Сообщения
7,722
Реакции
1,447
Credits
25,053
Буквально на днях, спустя три недели после выхода на работу, мой новый программист пишет такой же код, как и трое моих других опытных разработчиков, которые на том же проекте около года. В свою очередь эти трое создают единую архитектуру, дают одинаковые названия сущностям и пишут чистый код, что сильно упрощает проведение 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. Особого негатива я у него не увидел, наверное потому-что задача была поставлена в четких рамках, уже был составлен мануал, и нужно было проверить , что человек его прочитал. Результат был такой же, как и в первый раз. И тут меня осенило: оказывается, не обязательно учить людей самому, а можно это делегировать. А для того чтобы у «учителя» не было «молчаливого отрицания», всего-то нужно ему предоставить уже готовый материал и замотивировать. Мне это так понравилось, что я поставил это дело на поток. Теперь за обучение в моей группе отвечал самый опытный инженер, и я практически перестал заниматься этим лично.
 

GuDron

dumpz.ws
Admin
Регистрация
28 Янв 2020
Сообщения
7,722
Реакции
1,447
Credits
25,053
Передача опыта.

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

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

GuDron

dumpz.ws
Admin
Регистрация
28 Янв 2020
Сообщения
7,722
Реакции
1,447
Credits
25,053
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) Для того чтобы ребята не держали правила в голове и они были всегда под глазами, я перенес все данные из файлика с моего рабочего стола в “Для просмотра ссылки Войди или Зарегистрируйся” 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 месяца работы сильно вырастут.

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

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