Сайт Романа ПарпалакаБлогКлючевые словапромышленное программирование

промышленное программирование

Введение в скрам

— Проверено. Дать гению пять человек в подчинение, поставить четкую задачу и попросить организовать работу. Через неделю гений сам всё про себя поймет.
— Гений не поймет, он объяснит, какой народец некондиционный, читайте всё в блоге гения.

Баш

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

Зачем нужен скрам

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

Команда и спринты

Рабочая единица по скраму — скрам-команда. Она состоит из трех частей:
  • команда разработки — профессионалы, совместных умений которых достаточно, чтобы делать продукт;
  • владелец продукта — представитель бизнеса, знает текущее направление развития продукта, определяет приоритеты разработки;
  • скрам-мастер — проводит встречи, следит за соблюдением процесса, напоминает правила участникам, помогает улучшить рабочий процесс.

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

В идеале в команде разработки собраны все специалисты, необходимые для работы над продуктом: аналитики, дизайнеры, программисты, тестировщики. Взаимодействие в команде плоское. Размер команды не должен быть слишком большой, скажем, 5 — 9 человек, чтобы избежать излишних накладных расходов на взаимодействие.

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

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

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

Планирование

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

Вот что написано о цели в руководстве:

Цель Спринта – это установленный для Спринта ориентир, который достигается посредством выполнения части Бэклога Продукта. Цель Спринта формулируется во время его Планирования и объясняет Команде Разработки, для чего создается Инкремент.

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

Цель связана с наиболее приоритетной задачей, но не тождественна ей. Польза выбора цели в дополнительной синхронизации ожиданий. Например, на планировании выясняется, что команда разработки скорее всего не может «сделать фичу и выложить в бой», потому что другая команда должна доработать АПИ, админы — запустить новый сервис и т. д. Но по-другому сформулированная цель — «сделать фичу и продемонстрировать на тестовом окружении» — достижима, и на текущий спринт устраивает заказчика, который сам хочет всё посмотреть в действии до выкладки.

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

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

5 января 2019 года, 22:35     промышленное программирование · скрам     Оставить комментарий

Исправляем баги с помощью рефакторинга

Василий Половнёв в советах рассказывает, как исправлять баги:

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

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

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

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

Симптом

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

Попытка воспроизведения

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

Изучение кода

К сожалению, в Cityads было много legacy-кода. Логика обработки смс-кода была размазана по двум местам: генерированию кода перед его отправкой и проверке этого кода при вводе. В реализации присутствовали многие признаки говнокода. Код написан в контроллерах без дополнительных уровней абстрацкии, в императивном стиле. Время отправки, сумма к выводу и id внешнего счета хранились в разделяемой памяти — суперглобальном массиве сессии. Формат хранения — ассоциативный массив:

$_SESSION['sms_codes'][$account_id]['code'] = $code;
$_SESSION['sms_codes'][$account_id]['time'] = time();
$_SESSION['sms_codes'][$account_id]['amount'] = $amount;

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

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

Логирование

Когда баг нельзя воспроизвести локально, может помочь логирование. Чтобы понять, почему код работает не так, как ожидается, вы добавляете инстуркции для записи значений переменных в лог, например, в файл. Логировать полезно не все действия подряд, а только определенные, например, с вашего ip-адреса. Иначе в логах сложно разобраться.

Я залогировал значения переменных и увидел, что к моменту проверки кода в сессии было пусто, как будто код вообще не генерировался. Тем не менее, другие значения, не связанные с смс-кодами, в сессии присутствовали. Я не смог найти причину очистки. Код на серверах был одинаков. Сравнение конфигурации PHP ничего не дало.

Гипотеза

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

Я решил не искать, кто именно портит данные в сессии, а с нуля переписать обработку смс-кодов и уйти от хранения данных в сессии.

Рефакторинг

К этому времени мы подключили Symfony и писали новый код по принципам SOLID. Я написал сервис, в котором инкапсулировал логику работы с смс-кодами. Сервис принимал тройки значений (code, time, amount) в виде одного объекта (DTO), сохранял их в кеше (у нас был мемкеш) и при необходимости возвращал. Старый код через синглтон обращался к DI-контейнеру и доставал оттуда сервис.

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

Ссылки по теме

29 мая 2018 года, 23:42     промышленное программирование     Оставить комментарий

Промышленное программирование и область ответственности разработчика

Промышленное прогаммирование

Хочу поделиться опытом промышленной разработки программного обеспечения. Под словом «промышленная» я понимаю разработку приносящего деньги продукта в коллективе от нескольких десятков человек.

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

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

Аджайл-манифест разработки программного обеспечения

Начнем систематизировать знания о разработке с аджайл-манифеста:

Люди и взаимодействие важнее процессов и инструментов.
Работающий продукт важнее исчерпывающей документации.
Сотрудничество с заказчиком важнее согласования условий контракта.
Готовность к изменениям важнее следования первоначальному плану.

То есть, не отрицая важности того, что справа, мы всё-таки больше ценим то, что слева.

Это емкие, многогранные принципы. Мы к ним еще не раз вернемся. А пока посмотрим на одну составляющую первого принципа, а именно на то, как организуют взаимодействие с разработчиком.

Область ответственности разработчика

Недавно на хабре вышла статья про то, как Слак и мессенджеры вообще снижают продуктивность. В комментариях завязалась интересная побочная дискуссия. Первая точка зрения:

Никто никого не должен отвлекать по пустякам, вообще обычный разработчик должен в рабочее время заниматься только выполнением текущих запланированных задач и реагировать только на два типа сообщений:
1. Авария — что-то серьезное на продакшене или ошибка на уровне архитектуры, в первом случае срочно чиним, во втором останавливаемся и обсуждаем т.к. дальнейшая работа может просто оказаться бессмысленной. Если часто проблемы с продом — это чаще всего косяк тестировщиков, если хреново спланирована архитектура или выбраны не те инстументы — косяк архитекторов.
2. Блокировка — т.е. отсутствие реакции на это сообщение реально блокирует работу другого человека. Если есть большой поток блокирующих сообщений, то это либо отсутствие компетенции у других исполнителей — косяк того кто их нанял, либо хреновое планирование и распределение задач между исполнителями — косяк ПМа.

Если же разработчик вынужден по работе напрямую общаться с кем либо кроме ПМа и других разработчиков (например с заказчиками), то ему лучше сменить место работы!

Вторая:

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

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

Оператор ЭВМ Инициативный разработчик
Просит четкое техническое задание Просит объяснить бизнес-ценность задачи
Делает по требованиям, даже если они противоречат сделанному ранее Не любит переделывать
При обнаружении противоречий сообщает постановщику задачи
Не дает результат без менеджера и тестировщиков Работает самостоятельно
Знает, что значит «сделать»
Получает меньше денег Получает больше денег

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

Руководитель программистов должен учитывать при подборе и огранизации рабочего процесса особенности каждого способа. Первый свойственен водопадной модели, воторй — аджайлу. Если вы нанимаете инициативных разработчиков — готовьте бюджет. Если нанимаете операторов ЭВМ, нанимайте еще менеджеров и тестировщиков.

25 марта 2018 года, 19:03     промышленное программирование     Оставить комментарий
Поделиться
Записи