Показаны сообщения с ярлыком methodology. Показать все сообщения
Показаны сообщения с ярлыком methodology. Показать все сообщения

воскресенье, 1 декабря 2024 г.

От Trello к Obsidian: шаблон для управления проектами в стиле скрам

Введение

Давным-давно одна команда полюбила "Plus for Trello" — уникальный плагин для Trello, который стал одним из лучших инструментов для учёта рабочего времени и ведения скрама небольшой командой. В этой статье расскажем о том, как этот плагин помог организовать рабочий процесс, как Obsidian смог подхватить эстафету после его "смерти", и будет представлен проверенный временем шаблон проекта Obsidian для командной работы по scrum.

Plus for Trello: особенности рабочего процесса

Плагин "Plus for Trello" расширял функциональность Trello, добавляя к карточкам поля для учёта потраченного времени и оценок (spent/estimate). Уникальная особенность плагина заключалась в использовании специального синтаксиса в комментариях, который позволял вести детальный учёт времени по разным типам деятельности. Эти комментарии могли быть добавлены разными авторами в одну и ту же карточку, что давало полную картину всех действий.

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

  • plus! 0/8 Добавить estimate в 8 час задаче
  • fix! 7/8 Рендеринг дал сбой из-за бага в Chrome. Выполнил переоценку и добавил тесты.
  • fix! 5 Нашёл решение на http://stackoverflow.com/asd344dasd/
  • docs! 1
  • review! 1

Начало каждого комментария соответствует шаблону ТИП_ДЕЯТЕЛЬНОСТИ! SPENT/ESTIMATE [ДАТА_ВНЕСЕНИЯ] ТЕКСТОВОЕ_ОПИСАНИЕ. Таким образом, в карточке появлялись общие подсчитанные значения: 14 часов потрачено (spent), и оценка (estimate) на 16 часов (8 изначально заложенных). Можно было также посмотреть данные по срезам типов деятельности и исполнителей, что давало дополнительную аналитическую информацию.

Как мы использовали эти данные о потраченном времени и оценках

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

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

Смерть Trello и Plus for Trello

Осенью 2023 года случилось давно ожидаемое: Trello начало блокировать аккаунты, связанные с Россией, а Plus for Trello перестал функционировать из-за прекращения поддержки Web SQL в Chrome, а новый владелец стал "продавать" данные пользователей. Попытки найти альтернативы среди отечественных и open-source решений оказались неудачными — ни одно из них не могло заменить функциональность и удобство Plus for Trello. Наиболее близким был OpenProject, а по удобству, но не функционалу — Yougile.

Obsidian: далеко зашедшая шутка

Так в поле зрения попал Obsidian. Плагин Dataview превращает Obsidian в подобие файловой базы данных. Решение использовать его для замены Trello было своего рода шуткой и попыткой глубже изучить популярный инструмент. Главной задачей было обеспечить совместную работу нескольких членов команды и минимизировать конфликты при слиянии изменений.

В "шутке" за основу была взята концепция Plus for Trello, но адаптированная для Obsidian: каждый участник команды записывал свои комментарии за каждый день не в карточку, а в отдельный файл, ссылаясь на файл задачи. Это снижало вероятность конфликтов при объединении изменений в командной работе.

Шутка неожиданно затянулась, и Obsidian стал эрзац-заменителем Trello.

Шаблон Obsidian проекта на GitHub

На GitHub представлен шаблон agile-obsidian-template получившегося проекта. Для примера сгенерированы данные двух спринтов. Данные исключительно для иллюстрации — не стоит искать в них смысл. В readme шаблона более подробно описывается структура, взаимодействия с гит и другие особенности. В статье же пробежим по вершкам.

Структура проекта в Obsidian

Для начала работы требуются сам Obsidian, Git и клон репозитория Obsidian Vault, содержащий проект. При открытии хранилища (vault) будут автоматически установлены следующие плагины:

  • Dataview — делает файлы в Obsidian подобием базы данных.
  • Kanban — доска в стиле канбан, где каждая карточка представлена отдельным md-файлом.
  • Obsidian Git — синхронизация хранилища между членами команды через Git.
  • Templater — шаблонизатор для автоматизации действий.
  • Charts — плагин для создания графиков.

Рабочий процесс предполагает разбитие на итерации — спринты. Каждый спринт представлен отдельной папкой, содержащей основной файл и три дополнительные папки:

  • board.md — файл, при открытии которого загружается канбан-доска.
  • /tasks — папка с задачами. Каждая задача имеет свой md-файл, куда можно добавлять комментарии. Если задача из предыдущего спринта переносится в следующий, она сохраняет ссылку на файл задачи из предыдущего спринта.
  • /comments — папка с комментариями к задачам. Каждый член команды имеет отдельный файл для своих комментариев на каждый день.
  • /reports — папка для отчётов по спринту.

Основные интерфейсы

Скриншоты, иллюстрирующие основные элементы UI/UX использования шаблона:

Доска текущего спринта:


Основной отчёт, отражающий spent/estimate по задачам спринта:

Отчёт с разбивкой по типам деятельности спринта:

Карточка задачи, содержащая список всех комментариев:

Отчёт по внесённому времени в разрезе исполнителей:

Процесс создания отчёта по новому дню, заполнение и пуш на сервер:

Заключение

Шаблон agile-obsidian-template для Obsidian пока далёк от завершения, а некоторые возможности полноценного трёхзвенного приложения в рамках Obsidian недостижимы в принципе, но шаблон может быть полезен, так сказать, для "ценителей". Продвинутые возможности редактирования текста и горячие клавиши Obsidian обеспечивают, пожалуй, даже более быстрое и лёгкое ведение журнала.

Эксперимент неожиданно показал, что Obsidian может быть интересным инструментом для прототипирования в определённых случаях: есть простое подобие базы данных, средства пользовательского ввода, а кастомизация очень проста и удобна. Для того чтобы команда начала комфортно вести оперативную деятельность, как в Plus for Trello, потребовалось всего полдня хакатона.

Подход Plus for Trello с написанием плагина для браузера можно также реализовать в Yougile и других системах. Однако использование локальных данных имеет свои преимущества — они всегда остаются под контролем команды, и от этого уже становится сложно отказаться.

среда, 18 ноября 2020 г.

Можно ли сэкономить набирая junior специалистов?

Дисклеймер №1: По стопам предыдущих двух статей "Эффективность по Skunk Works" и "У нас нет ресурсов для ревью кода"

Дисклеймер №2: Безусловно разделение на junior-middle-senior, используемое в статье, крайне условное и мало связано с опытом работы, а градация сильно зависит от компании, в которой дается оценка. Однако мы живем в реальности, в которой на hh в вакансиях ведущих it компаний используется такая терминология, и все мы, так или иначе, понимаем о чем речь, и примерно какой набор требований предъявляется в том или ином случае. И предвосхищая дальнейший текст статьи, заверяю, что абсолютные величины не так важны для сделанных выводов.

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

Дисклеймер №3: Рассуждения по большему счету не про топ компании, в которых и так все в порядке, а скорее про остальное большинство. Так же разговор идет про технически сложные продукты, правда в возможность существования простых, в общем случае, особо и не верю. Простые продукты (вспоминая Пола Грэма и его книгу "Хакеры и Художники") вряд ли могут успешно существовать на конкурентном рынке, в противном случае их было бы слишком просто скопировать и повторить.

Давайте приведем возможные доводы за то, чтобы строить HR политику на наборе джуниоров и их последующем росте.

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

Практически все доводы несостоятельны. Давайте по порядку.


## Себестоимость продукта с джунами выше чем с профессионалами


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

 

 

 График построен на  моем опыте, но можно попробовать посмотреть на другие графики. Принимаем допущение, что уровень программиста соответствует ЗП. Конечно же он выглядит не справедливым.

 Фредерик Брукс, Пол Грэм, Дядя Боб считали, что высокопрофессиональные разработчики эффективнее остальных от пяти до десяти раз. Таким образом становится совсем очевидно, что каждый вложенный рубль в сеньора окупается гораздо быстрее, чем в джуниора.


"Мифический человеко-месяц":

>Руководители программистских проектов давно уже поняли, как значительны различия  в  производительности хороших и плохих программистов. Тем не менее результаты точных измерений  этой величины просто поражают. В одной из своих работ Сакмен,  Эриксон и Грант  измеряли  производительность группы  опытных программистов. Даже внутри этой группы отношение максимальной и  минимальной
производительности в среднем составило 10:1, а для  времени работы программы и затрат памяти - 5:1. Короче говоря, производительность труда программиста, получающего 20 тыс. долларов в год, может быть в 10  раз больше, чем у того, кто зарабатывает 10 тыс.  долларов. Обратное  также может быть  справедливо. Статистические данные утверждают, что нет никакой зависимости между опытом и производительностью. (Сомневаюсь, впрочем, чтобы это было верно всегда.)


## Коммуникация - узкое место


Продолжая сравнивать 3 джуниоров против одного сеньора нельзя забывать и о том, что на коммуникацию и синхронизацию 3 джуниров уйдет порядка 10-20% общего времени. Чем больше людей, тем больше издержек. Таким образом, набор джуниоров идет и против стратегии  сохранения наименьшего количества разработчиков работающих над проектом. То, о чем говорил Келли Джонсон в Skunk Works, ну и конечно же Брукс.


## Джуниор - это инструмент, но не самодостаточная единица


Джуниор как правило совершенно не способен решать задачи высокой сложности. И есть иллюзия, что он может решать простые задачи. Да может, но если это задачи в вакууме. Но в рамках сложного продукта простота задачи может быть не столь очевидна.
Тут уже нужно виденье, которое есть только у сеньора. Моя практика говорит, что простых задач в сложных продуктах нет, есть лишь степень ответственности сеньора. Джуниор может не заметить, что "простая" задача на самом деле требует сложного решения, не увидеть потребности в рефакторинге. Зрение джуниора достаточно узко и не глубоко. И требует тщательного контроля, усиленного вникания старших товарищей в суть "простой" задачи, что бы не пропустить сложность. И как правило такое погружение и выполнение задачи по времени превышает время самостоятельного выполнения задачи сеньором.

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


## Подобное к подобному


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

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



## Наем профессионала vs джуниора


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

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


## Джуниоры крадут время у наиболее боеспособных единиц


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

## Подводя итоги:  команда мечты


Получается что вообще сторониться джуниоров? Куда же им тогда податься?
Конечно же джуниоров можно брать, но на "сдачу". Наем джуниоров как стратегия на далекое будущее, в некотором роде рискованные инвестиции. По моему опыту на команду из 5 человек максимально допустимо иметь 1 джуниора и 1 мидла. И это не история про то, что джун и мидл это тестеры, devops'ы, техписы.


Допустим у нас на команду есть бюджет 550-600 т.р.
Можно пойти двумя путями и попытаться сформировать классическую команду из 7 человек, либо сделать упор на  максимальное количество профессиональных разработчиков.

Попытаемся представить как могла бы выглядеть первая команда:

### Команда строящаяся на основе джунов


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

1) Сеньор-лид - 150 т.р. (8х  - 4x (Половина времени на обучение и организацию)  = 4x)
2) Мидл? - 110 т.р. (5х - 1х Обучение = 4х)
3) Мидл? - 80 т.р. (2x)
4) Мидл? - 65 т.р. (1x)
5) Мидл? - 60 т.р. (1x)
6) Джун - 55 т.р. (0.2)
7) Джун - 50 т.р (0)

Общая производительность без учета потерь на коммуникацию: 12.2x
Принято считать, что добавление каждого нового члена в команду отъедает до 5% общего времени на коммуникацию. Т.о. общая производительность с учетом потерь на коммуникацию: 12.2x * 0.7 = 8.54x
КПД: 66 т.р. за 1x производительности.

Проблемы этого варианта, кроме низкого КПД:

* Сложность уменьшения текучки кадров. Много сотрудников находятся на этапе быстрого роста ЗП. Уровень ЗП должен соответствовать навыкам и рынку, а это бывает сложно синхронизировать. Проще уйти в другую компанию с повышением ЗП. Ко всему прочему, можно допустить, что такое стремление сократить издержки на людей негативно отразится и на ЗП ведущих разработчиков, заставив их чаще посматривать на сторону.
* Сложность удержания бюджета. Зарплаты у джуниоров на начальных этапах растут опережая инфляцию и производительность. 

### Команды на основе сеньоров


1) Сеньор-лид - 170 (8x - 2x (Орг. деятельность) = 6х)
2) Сеньор - 160 (8x)
3) Сеньор - 160 (6x)
4) Мидл - 100 (3x)

Общая производительность без учета потерь на коммуникацию: 23x
Общая производительность с учетом потерь на коммуникацию:23x * 0.8 = 18.4x

КПД: 32 т.р. за 1x производительности.

Дополнительные плюсы, кроме высокого КПД:

* Большой запас по КПД дает возможность увеличения ЗП для удержания сотрудников, прежде чем команда станет не эффективна по сравнению с командой на джуниорах
* Продукт качественнее (быстрее, эффективнее, юзабельнее, проще)


## Выводы


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








среда, 4 ноября 2020 г.

Эффективность по Skunk Works

 Прочитал "Skunk Works. Личные мемуары моей работы в Локхид"

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

История SkunkWorks в первую очередь взрывает своей эффективностью. Принципы работы которыми делится Бен Ричи (глава SkunkWork в 70-80х) не являются откровением как минимум со времен "Мифического человеко-месяца". Однако книга на столько яркая, что заставляет еще раз оглянуться на разработку в которой участвуешь и задуматься о том, куда уходит время, так ли нужны нам эти митинги, таски, отчеты, код ревью, планирования, ретроспективы для создания продукта. Что если просто выбросить хотя бы половину из этого миллиона ритуалов? 

SkunkWorks - маленькое секретное подразделение Локхид, которое могло строить прорывные проекты с безумно высокой эффективностью. U2 полетел за 8 месяцев, SR-71 Blackbird - самолет способный в 62 году продолжительное время летать на 3 Max разработала команда из 75 инженеров-проектировщиков, программа прототипа F-117A от идеи до первого полета за каких то 30 млн. $  и 2 года.

Как команда из меньше чем 100 инженеров могла создавать проекты оставившие такой существенный след в истории? Сравните их со списком фич последней мажорной версии вашего продукта.  

Успех SkunkWorks много кто хотел повторить, однако никто не готов был принять методику и поверить в людей.

Бен Ричи говорит, что они не были избалованы комфортом. У них не было отдельных кабинетов, массажных кресел, офис менеджеров, этажных хозяюшек. Столы стояли впритык, люди сидели буквально в полуметре друг от друга.

Но у них было другое:

  • Повернутость на минимизации всей лишней деятельности.
  • Устранение преград для коммуникаций (от слесаря до инженера-проектировщика расстояние броска камня, от специалисты до специалиста расстояние вытянутой руки)
  • Высокопрофессиональный коллектив, лучшие из лучших.
  • Высокая мотивация и сплоченность коллектива, несмотря на мало комфортные условия работы. Что являлось мотивом для профессионалов? Работа в коллективе профессионалов, интересная работа, результат. Одно тянет другое.
  • Максимальный уровень свободы, минимальный уровень бюрократизма
  • Открытая среда - "Мы поощряли наших людей работать творчески, импровизировать и пытаться использовать нетрадиционные подходы к решению проблем и не мешали им."
  • "Мы стремились достичь эксплуатационной надёжности Шевроле, а не совершенства Мерседеса. За 20% усилий достичь 80% результата. Имей бы мы тогда сегодняшние мощные компьютеры, это бы ускорило проектирование и упростило бы испытания, но совершенство редко было целью Skunk Works. Если мы ошибались в расчётах на полкилограмма или на градус, это не сильно беспокоило нас."
  • Если надо нарушить правила - значит надо нарушить. Это не было проблемой при должном уровне компетенции, которая впрочем падала по мере роста.
  • "Всеобщее управление качеством". За контроль качества ответственны все причастные к процессу создания изделия.
  • "Уникальные материалы или детали должны избегаться,  везде где возможно. Уже готовые детали должны использоваться даже в ущерб лишнему весу"
  • В начале дешевый прототип.  

 
Кто то увидит здесь отголоски Agile, XP, Lean. Да! Все старо как мир. А еще история близки в том, что Agile тоже мало у кого работает.

Одно время, Бена Ричи сманивал Нортроп. И вот, что ответил Бену Келли:

“Чёрт возьми, Бен, я не верю ни одному слову, которое этот парень тебе сказал. Я поставлю своё ранчо на то, что Нортроп не создадут свой собственный Skunk Works. Компания даёт пустые обещания, потому что видит, насколько успешны мы. На самом деле менеджеры не верят в идею независимых подразделений, где из-за секретности они не могут точно знать, что происходит внутри. Не обманывай себя, у нас в менеджменте тоже есть люди, которых возмущаю я и наша независимость. Люди из аэрокосмической промышленности, даже уважающие нашу работу, хорошо знают, что чем меньше людей работает над проектом, тем меньше дохода можно получить от крупного правительственного контракта и возрастающих издержек. Сохранение небольшого количества людей снижает возможности для повышений. Чёрт, на главном заводе они дают повышение за большее количество людей, находящимся под руководством; я даю повышение тем, кто контролирует меньше людей. Это означает, что такие люди делают больше и принимают на себя больше ответственности. Но большинство руководителей думает совершенно другим образом. Руководство Нортроп ничем не отличается от всех остальных в этом бизнесе: все они пытаются построить империю, потому что именно так их учили делать. Эти парни - сплошь эксперты в прикрывании своих задниц путём выноса решений на голосование. Они никогда не согласятся создать подразделение, которое абсолютно не будет в них нуждаться. Они играют в игру под названием “Контроль”, и если Skunk Works действительно работает, как надо, то контроль это именно то, что они не получат."


Если вы не умеете готовить, то единственный путь получить хороший борщ - соблюдать рецепт до запятой. Незначительные отклонения могут погубить все дело. В современном IT есть множество проверенных рецептов на многие случаи жизни. Но на словах у всех Agile и скрам и прочие другие слова. На поверку много оговорок и очередной локальный исторически сложившийся подход с "элементами из agile" в рамках красной корпоративной культуры.

"Любая компания, чьё положение зависит от разработки новых технологий, должна иметь в своём составе Skunk Works; сейчас существует примерно пятьдесят пять подобных подразделений в различных отраслях промышленности – это не очень много. Но если в Локхид Skunk Works был чрезвычайно успешен, почему сотни других компаний не попытались сделать тоже самое? Одна из причин, по-моему, заключается в том, что большинство других компаний не понимают концепцию, задачи и ограничения, в то время как многие другие не хотят предоставлять свободу и независимость, которые являются необходимыми компонентами для успешного функционирования предприятия типа Skunk Works."

воскресенье, 18 ноября 2018 г.

Парное_программирование VS ревью_кода


 Данная заметка - реакция на статью http://alexnesterov.com/code-review/, где практика code review рассматривается как антипаттерн, а парное программирование как способ решить задачи ревью кода правильно. 
Конечно же, у парного программирования и код ревью есть пересекающееся множество целей. Но парное программирование не в силах полностью закрыть потребность в ревью кода.

Минусы парного программирования

Минусы full-тайм парного парного программирования которые сразу бросаются в глаза:
  1. Практика full-тайм парного программирования доступна не всем компаниям:
    • Не каждый кандидат может/согласится работать в такой методологии. 
    • Вопрос организации пар тоже не самый простой.
    • Все остальные процессы в компании должны затачиваться под парное программирование: организация рабочего места, распорядок дня (приход-уход, удаленная работа, больничные, обеды).
    • Т.е. отрезаем себя от части рынка труда и добавляем дополнительные сложности. 
  2. Фул-тайм парное программирование не всегда эффективно. Есть множество достаточно простых  или рутиных задач в которых от создание пары не получить буста в производительности или качестве. Т.е. фул-тайм парное программирование просто получение максимального качества без учета экономической обоснованности. 
  3. Парное программирование не решает всех задач ревью код
    • Как происходит распространение знаний между парами? Ротациями пар? На сколько это эффективно и какой лаг? 
    • Код ревью под парами (инструменты настроены и все знают как ими пользоваться) позволяют в любой момент подключить нужное количество ревьюверов в асинхронном режиме) 

Золотая середина?

Наш выбор фул-тайм практика ревью кода с подключением парного программирования по необходимости: 
  1. Мозговые штурмы или решение сложных задач требующих скорейшего решения. 
  2. Менторство для новичков. 

Мифические проблемы ревью кода

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

Потеря контекста

Это не проблема, а сигнал что в процессе разработки что то не так. Контекст и мотивация автора должна быть понятна из ревью. Про это у меня есть статья http://cemick.blogspot.com/2015/08/svn-git-git.html
Программист  - не археолог разбирающий наскальные записи прошлых поколений. Если контекст и мотивация не понятная на ревью, она будет не понятна через неделю другому программисту который попадет на этот участок кода и автору  уже через месяц.
Ко всему прочему мы к ревью часто прикладываем ссылку на поднятый инстанс или бинарник, что бы ревьювер мог проверить работающее приложение, если есть в этом потребность. 

Это не баг, это фича

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

Отсутствие эмпатии

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

Нарушение потока автора

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


Что же такое ревью кода

  1. Это гибкость
    Можно организовать менторство.
    Можно в любой момент подключить нужное количество людей с известными всем правилами обсуждения и документированием.
    Можно выпонять асинхронно и синхронно. 
  2. Контроль соблюдения стандартов и правил оформления кода 
  3. Распространение знаний о важных изменения в проекте. Об изменения в архитектуре и в сквозной части функционала необходимо извещать все заинтересованные стороны.
  4. Повышение квалификации 
  5. Сохранение дополнительной метаинформации по коммиту: обсуждение в рамках ревью остается задокументированным. 
  6. Распределение нагрузки по контролю за кодовой базой или распространением информации с тимлида или начальника отдела на всех. 


среда, 26 августа 2015 г.

Что дал переход с SVN на Git или Git как ключ для синергии хороших практик

    Год назад мы в проекте выполнили переход с SVN на Git. Нас привлекали возможности бранчевания и работы с репозиторием без сети. "Сарафанное радио" регулярно доставляло сообщения о преимуществах модели распределенных систем контроля ревизий. В итоге, переход себя полностью оправдал, и Git раскрыл множество прекрасных возможностей, о которых во время перехода даже не подозревали. Но самое замечательное, что побочным эффектом оказалось поднятие общего уровня и культуры разработки.
   
     В первой части я расскажу о своих ощущениях после перехода на Git.  Если вы уже знакомы с ним, то возможно вам следует перейти сразу ко второй части, где я попытался снизить градус слащавости и пафоса и перейти уже наконец то к делу. Во второй и третьей части я коснусь практических вопросов, которые проливают свет о влияние гита на культуру разработки. 

Дифирамбы Git'у     


    Часто пользователи SVN не видят обоснованных причин для перехода на Git (на самом деле слово Git можно смело заменить на DVCS, однако опыт у меня есть только связанный с Git, потому дальше Git будет мелькать чаще). И в действительности среди плюсов на поверхности лежит лишь концепция распределенности и мифическая легкость ветвления (бранчевания).   Как сказал мой друг, парадокс гита заключается в том, что вначале не можешь понять чем Git хорош, а потом не знаешь как это рассказать. Это надо только прочувствовать. Сухое сравнение разных концепций не всегда убедительно. Многие возможности есть в обоих VCS.  А по некоторым возможностям SVN имеет преимущества. Кто-то скажет, что у них разные области и назначения, но используют то их чаще всего одинаково. Технические аспекты лучше всего смотреть в официальном руководстве для гита https://git-scm.com/book/ru/v1 (на мой взгляд лучшее руководство по гит), поэтому дальше в статье будут ощущения и эмоции. 

     С каждым днем только крепнет уверенность, что уже ничто не заставит вернуться обратно. Сказать честно, вначале было много сомнений, стоит ли игра свеч, а не будет ли это потеря времени? Теперь смело заявляю, что Git это намного больше чем SVN, или VCS в парадигме SVN (sic!).  Система хранения ревизий с точки зрения SVN является просто хранилищем кода и его изменений, преследуя такие простые практические цели как обмен общими файлами проекта, навигация и возможность вернуться к нужной версии или найти виновника и задачу, в рамках которых был поломан продукт. Слышу от оппонентов: "мне Git не нужен, так как я работаю один/у нас нет веток/в гите нельзя работать с бинарными форматами/ гит слишком сложен/ и т.п."  На самом деле он нужен всем (программистам, дизайнерам он может и не подходить) и вот почему.

     Git меняет представление о назначение VCS. Поднимает культуру работы с кодом проекта.  История изменения кода не менее важна, чем сам код, а может даже более.  Git предоставляет возможности выставить акцент на истории изменения кода. В системе контроля версий начинает формироваться слой документации и требований к продукту в самой непосредственной близости к коду.  И немаловажным фактором является возможность следовать новым нехитрым практикам работы с репозиторием и кодом, которые дисциплинируют разработчика. Что положительно сказывается на коде. Код становится более логичным, красивым и вылизанным.

    Почему  же в гите все это можно обеспечить? Краеугольный камень - это распределенность. Что она дает? Обычно говорят, что распределенность дает возможность работать без подключения к интернету и обмениваться ревизиями минуя центральный репозиторий. Да - это верно. Но не на это я хочу  обратить внимание. Главное, что репозиторий у вас ЛОКАЛЬНЫЙ. Вот именно так: капсом и болдом.  Это позволяет манипулировать ветками и коммитами без опасения повлиять на работу коллег. У нас есть правило, звучащее как "в репозиторий должен попадать только рабочий, целостный код, прошедший ревью". На сколько сложно это правило соблюдать в SVN, на столько легче его соблюдать в гите.
     Что же еще делать в гите легко и является ежедневной рутиной, о чем SVN джедаи могли бы только мечтать?  В Git'e легко создавать ветки, выполнять слияние, манипулировать коммитами. Вам, как заправскому шулеру, ничего не стоит  строить цепочки коммитов, дробить коммиты на более мелкие, менять коммиты местами, менять описание текста коммита и его состав.  Каждая операция требует минимального времени выполнения, никакой передачи данных по сети или копирования каталогов. 
     Ну ок. Все мы уже поняли, что Git хорош как Чак Норис в ковбойской шляпе и из хорошей задачи можно устроить отличный фарш из коммитов. Но зачем? Вот типичные моменты рабочего процесса под Git:
  • Ветки создаются под каждую задачу или просто для проверки какой-либо идеи;
  • Коммиты создаем часто, очень часто. Хотим ли особо акцентировать внимание на изменение в коде либо просто закончили итерацию, на все один ответ - коммит. В Git нет проблемы зафиксировать каждый логический блок изменений в рамках задачи отдельным коммитом. В SVN такое желание приведет к неконсистентному состоянию кода в центральном репозиторие;
  • Увлеклись, написали кучу кода, и вот у нас в одном файле изменения, которые относятся к разным логическим частям? В Git это совершенно не проблема - разные логические части одного файла Git позволяет зафиксировать разными коммитами; 
  • Забыли написать тесты и проверить их работу до написания функционала? Не проблема, пишем тесты и новый коммит вставляем перед коммитом задачи;
  • Хотим отправить изменения в центральный репозиторий, но перед этим избавиться от избытка лишней информации и вместо 15 коммитов, отправить 4 сгруппированных? Все верно - и это не проблема. 
  • Я уже не говорю про классические преимущества DVSC, такие как совместная работа над одной задачей разных членов команды. 
     Звучит как фантастика? Отнюдь - просто обычные будни работы с Git. Когда долго не работаешь с SVN забываешь, что там эти операции не возможны. Гит дает чувство пьянящей свободны, нет практически ничего, что вы не могли бы в нем делать. Все делается очень легко: манипулирование ветками и коммитами напоминает игру. И вы от это получаете удовольствие, потому что все ваши, даже сложные, задумки реализуются, а желания предугадываются.  Ну и конечно вы получается удовольствие от того, что в памяти всегда свежи ощущения от SVN.

Наши практики по работе с репозиторием кода

     Гит добавляет в методологию разработки новые аспекты, которых вовсе не ожидаешь, пока не начнешь его использовать.  Эти аспекты мы раскрывали постепенно, шаг за шагом вводя простые правила:
  
1.   На первом шаге у нас была одна постоянная ветка, бранчи использовались очень эпизодически и не было стабильной версии продукта.  Да и так бывает. Бывало даже так, что одним коммитом фиксировалось сразу несколько задач. С этого мы начинали. 
2.Потом появились ветки SVN (до SVN использовали VSS  и Perforce). SVN - хорошая система. Какое-то время использовали собственную модель бранчевания, потом сдались и перешли на стандартную раскладку trunk, tags, branches. В branches  мы создавали ветки только под большие задачи. Прошло много времени, но я хорошо помню боль и отчаянье от работы с ветками в SVN. Это было долго - долго создавать ветки, долго переключать, долго смотреть лог, а слияния веток превращались в испытание. Но с проблемами можно было мириться, если работать только с долго живущими ветками.
3.А следом появилось ревью кода. Это была практика, которая все перевернула. Сейчас мне сложно представить разработку без ревью.
4.Идеальным дополнением к ревью кода стал Git. Модель Git (DVCS) как нельзя лучше подходит для ревью кода. Следующие пункты раскроют это утверждение.
5.
Первым делом мы ввели правила написания текста коммита. Как писать коммит у нас жестко формализовано. Сами правила начали появляться еще при SVN, но только переход на Git заставил к ним относиться строго. Главное требование гласит: текст коммита обязан содержать мотивацию принятия решений и изменений, присутствующих в коде коммита. Перед выкладыванием на сервер каждая задача проходит ревью кода. Ревью кода выполняется с помощью инструмента CodeReviewer. И вот тут основной момент - ревьюверу задачи должно быть понятно все только на основе информации из коммита: непосредственно кода и текста описания коммита.  Если возникают вопросы, то описание коммита перерабатывается.  Можно найти множество плюсов подобного подхода:
  • Экономия времени. Раньше приходилось  многократно пересказывать и отвечать на одни и те же вопросы, если ревьюверов несколько. 
  • Саморевью и самоконтроль. Описание должно быть убедительное, а знания о проблеме систематизированы.  Часто бывает, то что убедительно в голове, на "бумаге" уже не столь явно. Приходилось сталкиваться с ситуацией, когда написание текста коммита приводило к полной переработке решения. Качественное описание порождает качественное решение.     "Так подожди, это же явно следствие, а не причина, необходимо установить причину", - говорит нам рациональная часть нас, "Так делать нельзя, иначе меня все равно завернут на ревью, а мое позорное описание останется на веки вечные в истории".  Однако если есть какие то условия которые толкают зафиксировать неидеальное решение, лучше их указать в тексте коммита и написать, например, что причиной скверного решения была необходимость закрыть задачу в короткий срок. В будущем люди скажут спасибо и не будут фантазировать, почему именно так было сделано, и смогут выработать наиболее верный подход к проблеме. 
  • История  коммитов теперь стала рассказывать гораздо больше и наиболее востребованную информацию. 
Раньше типичные коммиты были вот такими:
  • + мелкие исправления
  • + исправлена ошибка List index out of bounds(0) связанная с бендами
  • *refactor CreateControl method
  • *fix popup message window drawing
  • +Неблокирующее выполнение SQL-блоков. Задача 12862
  • fix: Определение паскаль операции по незакрытому тэгу <Pascal ; Удаление выборки из кэша при выгрузке библиотеки
  • + Выгрузка библиотек при снятии/установке флага использования кэша метаданны
Полный зоопарк стилей и практически полное отсутствие информативности. Чтобы понять, что же сделано в коммите, необходимо смотреть код и собирать по крупицам информацию из разных источников. Разработчики, которые заползали в такой код, могли многократно ходить по одним и тем же граблям. А про автора думать самые нелицеприятные вещи, задаваясь вопросом под какими запрещенными веществами код был написан. Ирония заключается в том, что нередко рассерженный разработчик является автором злосчастного коммита.
Теперь текст коммита стал вот таким:
"fix: исправить фокусировку на следующию ячейку после нажатия Enter #issue 40436

#Проблема 
Фокус переводился совершенно рандомно, без привязки к группировке колонок и визуальному порядку.

#Причины
В #problem-hash 234816912 в погоне за многострочными записями поломали наш механизм переход по горячим клавишам. 

#Решение
Решено задействовать встроенные в DevExpress методы перехода на следующею ячейку и отказаться от нашей логики, которая была написана для довольно старой версии DevExpress компонентов. Во-первых, в новой используемой версии девэкспресса появились вложенные банды. Похоже по истории изменений версий DevExpress и по их коду, что они и старые баги поправил, которые мы закрывали нашей реализацией. Во-вторых,  не удалось заметить, что DevExpress коллекция VisibleColumns не отсортирована, как написано в комментарии к нашему методу сортировки видимых колонок (проверялась и отсортированность колонок после перемещения их во время выполнения).Переход кнопками"вверх" "вниз" оставлен прежний, так как работает." 
Бывает получаются и вот такого размера тексты коммита

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

В SVN это правило было тяжело соблюдать. Как правило, задача уходила на сервер одним коммитом, что бы не получить в централизованном репозитории не консистентного состояния. Описание всех изменений в одном коммите теряет свою красоту и эффективность. В git'е каждую задачу можно декомпозировать до небольших логических шагов, о чем в следующем правиле.
6.
Правила оформления задачи в ветках.

Каждую задачу, как правило, можно декомпозировать на несколько шагов. Отделив, например, рефакторинг от непосредственно кода, исправляющего ошибку. Каждый шаг - отдельный коммит в отдельной ветке задачи. В последствии вся ветка попадет в центральный репозиторий, сохраняя для поколений структурированное решение задачи. Теперь даже коммит, который был выполнен "заодно" и не являющийся непосредственно необходимым для закрытия задачи, находится в контексте задачи (в той же ветке), позволяя видеть цель и мотивацию автора.
Задача в  SVN  - это большой, размазанный по разным модулям патч.  Больших усилий стоит разобраться в таком патче. Гораздо проще, когда каждая задача - это структурное решение, и можно пробежаться по отдельным шагам. В таком решении отделяются "зерна от плевел". 
Репозиторий стал неотъемлемой частью кода проекта. 


Пример:
Пример ветки по ускорения открытия карточек  где несколько коммитов с рефакторингом и другими вспомогательными действиями предшествовали коммиту решающему поставленную задачу

По ходу ревью в код могут вносится изменения, каждое такое изменение может вносится squash коммитом. Это коммит, который в последствие с помощью команды rebase можно объединить с другим коммитом (что бы ощутить мощь Git достаточно пробежаться по оглавлению способов изменить историю https://git-scm.com/book/ru/ и http://97things.oreilly.com/wiki/index.php/Record_your_rationale).
Таким образом, можно будет и в ревью видеть развитие мысли автора. А после завершения ревью одной командой rebase можно изменить историю и получить красивое дерево коммитов, без лишнего мусора, объединив squash, fixup коммиты с базовыми.
7.Правило "юнит тесты до функциональности". Это правило говорит о том, что юнит тесты должны располагаться в дереве коммитов до исправления ошибки, которую они тестируют. В результате всегда можно проверить работу юнит теста до исправления ошибки и после. Убедиться, что тест и исправление написаны верно.

Пример:

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

Про культуру 



     Система постоянно меняется, практически невозможно постоянно актуализировать все требования к приложения и его описания. Но теперь репозиторий взял на себя новую ответственную роль. Стал рассказывать не только кто и когда написал код, но и почему(такую роль бывает берет на себя багтрекер, но это слишком далеко от кода). Можно проследить мысль автора, узнать мотивы. Это формирует еще один уровень метаинформации. С помощью такого слоя информации мы стараемся закрыть наиболее критическое место описания системы. Практика показывает, что гораздо проще восстановить предисторию и все причины принятия конкретного решения для будущей переоценки, если они привязаны к коду  и расположены прямо в репозитории. Почему важно сохранять подобного рода информацию можно почитать еще здесь 97things.oreilly.com/wiki/index.php/Challenge_assumptions_-_especially_your_own и во многих других местах.  Но при при чем здесь культура?

    Чтобы понимали, что я имею в виду под культурой, приведу отрывок из книги Бориса Евсеевича Чертока "Ракеты и Люди", за который меня наверное уже недолюбливают как друзья, так и коллеги, слишком уж часто я его вспоминаю:
"В первые годы работы над ракетной техникой практически никто из руководителей, критикующих завод, не мог конкретно сформулировать, что нужно сделать для повышения культуры производства, определить роль каждого начальника цеха, мастера и рабочего. Было слишком много общих решений. Устинов беспощадно расправлялся с начальниками цехов и производств за грязь и бескультурье. При посещениях завода он начинал с туалетов. Обычно в цехах задолго до подхода к туалету разносился характерный «аромат». В самих туалетах надо было ходить по лужам. Устинов приходил в ярость и гремел: «Какой сортир, такой и начальник цеха. Пока не добьетесь образцовой чистоты в своих сортирах, не будет чистоты и в цехах».С тех пор прошло очень много лет. Проблема чистоты общественных туалетов на наших заводах и в институтах так же, впрочем, как и в стране в целом, не решена. Это оказалось куда труднее, чем создать самое грозное ракетно-ядерное оружие и завоевать мировой приоритет в космонавтике.Явный дефицит культуры, общей производственной чистоты и гигиены до сих пор является одной из причин низкого качества многих отечественных изделий. За время войны и в последующие годы забота об элементарном комфорте в цехах, создание рабочему достойной и привлекательной общей обстановки считались излишней и непозволительной роскошью. Затраты на чистоту, комфорт, элементарный сервис с лихвой окупаются повышением производительности и качества. "


  Если театр начинается с вешалки, то проект начинается с репозитория. Отношение к репозиторию закладывает отношение ко всему проекту. Аккуратность, формализованность, структурированность, обоснованность, ответственность и прозрачность  - качества, которые культивируются приведенными выше правилами работы с репозиторием, переносятся и на другие аспекты проекта. Сам workflow выполнения задачи сопротивляется поспешным, не продуманным, ошибочным и не обоснованным решениям. Код должен выглядеть хорошо и аккуратно не только внутри, но и снаружи. Мелочей не бывает. При переходе на Git о таких вещах, к сожалению, почти не задумывались. Git конечно, не серебряная пуля и не Святой Грааль, но крайне эффективный инструмент, который может сильно изменить ландшафт методологии разработки.

    Гит раскрывает свои возможности постепенно. Постоянно открываем что-то новое. В начале используется базовый набор команд. Но потом постепенно открываются все новые и новые возможности и пути оптимизации операций и повышения собственной эффективности. Кажется, что мы используем от 20 - 40% возможностей Git. Мы продолжаем познавать Git, постоянно экспериментируем и дорабатываем наши правила и стандарты. Возможно читатель поделится и своими успешными практиками. 

Несколько полезных ссылок

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