За 15 лет работы разработчиком я обнаружил, что ложные убеждения о человеческой природе — основные враги хорошей декомпозиции. Если знать о них и стремиться не угодить к ним в ловушку, со временем можно сформулировать советы по созданию качественной декомпозиции. Так произошло со мной, и я спешу поделиться этим знанием.
Фича (feature) — бизнес-возможность, автоматизируемая в программном продукте. Это англицизм, который широко применяется в ИТ-индустрии. Я не нашёл для него хорошего русского аналога.
Декомпозиция (уровня разработки) — процесс разделения работы над фичей на отдельные задачи, часто включающий выбор исполнителя. Также декомпозицией называют результат процесса декомпозиции, то есть совокупность получившихся задач.
Смётка — способность человека строить в уме модель функционирования механизма или природного явления, предсказывать поведение и находить причины неполадок посредством сосредоточенного усилия и интуиции. Это определение соответствует пониманию из книги «Дзен и искусство ухода за мотоциклом» и уточняет более общее значение из словаря: способность быстро соображать, рассчитывать.
Более 5 лет я работаю бэкенд-разработчиком в FunBox. В компании мы считаем, что хорошие продукты — результат развитой инженерной культуры и стремимся практиковать этот принцип в разработке решений для мобильных операторов. Тут есть свои особенности стека и процессов, но есть и универсальные аспекты, применимые в любой предметной области. Один из них — подход к декомпозиции. Благодаря продуктовому характеру работы и инженерной культуре мне удалось получить опыт и озарения, о которых я не могу молчать.
Навигация по статье:
- Контекст
- Ложные убеждения о человеческой природе
- «Закон Паркинсона»
- Континуум стилей декомпозиции
- Человечная декомпозиция С этого раздела начинается практически применимая информация
- Стратегии декомпозиции
- От прецедента к должностной инструкции
- Источники
- Changelog
Контекст
В статье речь идёт о ситуации, когда на уровне бизнеса уже определено какую проблему нужно решить и сформированы по крайней мере бизнес требования. Имея эти требования, нужно организовать непосредственный процесс разработки. Под декомпозицией в статье понимается именно декомпозиция уровня разработки, а не декомпозиция уровня бизнес-анализа.
К своим озарениям я пришёл в рамках разработки B2B продукта, находящегося в промышленной эксплуатации. Астрактно обрисую типичную фичу. Допустим, фича будет содержать бизнес-агрегат из пары моделей (сущностей), для которого нужно реализовать экраны создания, редактирования, просмотра и удаления. Ещё нужно реализовать алгоритм вычисления чего-то связанного с этим бизнес-агрегатом, а результат высислений отправить на email. Предполагается, что сверху фича оценена хотя бы 10-12 дней. В ней достаточно пространства для творческого осмысления и проектирования. Команда состоит из профессионалов разного уровня от младшего до старшего. Команда включет тимлида, который стремится в том числе заниматься кодированием, чтобы не терять ощущение професии, продукта и сохранять внутреннюю мотивацию. За границами команды никого не интересует как происходит процесс разработки, и никто в него не вмешивается. По крайней мере пока всё в порядке.
Народная мудрость гласит: «слона нужно есть по частям». Полезно разделить разработку всей фичи на задачи меньшего размера, чтобы снизить риски, сфокусировать усилия и повысить управляемость процесса. Я расскажу как я это делаю, как к этому пришёл, и от чего ушёл. Последнее для меня наиболее важно.
Ложные убеждения о человеческой природе
Следующие ложные убеждения о человеческой природе могут приводить к неудачным решениям при декомпозиции:
- Человек от природы порочен, и только давление общества заставляет его сдерживать свои порывы.
- Человек ленив, и его нужно заставлять работать, иначе он будет прокрастинировать.
- Человек склонен до бесконечности улучшать любой достаточно хороший результат, даже если это не несёт никакой ценности заинтересованным лицам (перфекционизм).
- Человеком движет жажда материальных ценностей для себя (эгоизм и алчность).
- Человек нуждается в подчинении и в том, чтобы ему подчинялись (авторитаризм).
- Человек не любит людей и стремится избегать взаимодействия с ними в процессе решения рабочих и жизненных задач (мизантропия).
Когда я называю эти убеждения ложными в отношении человеческой природы, вот что я имею в виду. Даже если время от времени эти свойства бывают присущи конкретному человеку на конкретном этапе его духовного развития, это не значит что все люди таковы или что они не могут преобразиться. Следовательно, не стоит класть эти частные случаи в основу видения и выстраивать стратегию поведения, считая их общезначимыми. Это обрекает людей на страдания и не даёт раскрыть свои возможности. От этого как раз снижается продуктивность за которую ведётся борьба.
Преодолев эти убеждения, можно глубже понять ценность человечной декомпозиции работы, хотя это преодоление не требуется для применения советов и практик данной статьи. Предположу, что опыт их применения может помочь сформировать более истинные представления о человеческой природе.
Опровержение этих убеждений не является предметом данной статьи. Над этим бьются философы и духовные лидеры на протяжении всей истории, и для каждого человека поиск опровержений будет глубоко личным. Я лишь вскользь коснусь возможных направлений поиска, до которых сам дошёл на данный момент.
Агностикам в вопросе существования высших сил может быть ближе миросозерцание гуманистов, например Эриха Фромма. Я попытался кратко сформулировать своё понимание миросозерцания гуманистов в докладе «Гуманистическая декомпозиция работы».
Спустя полгода после доклада я познал более глубокое христологическое, мистическое, персоналистическое миросозерцание Николая Бердяева. Попробую кратко суммировать по памяти своими словами. Следуя своей интуиции, Бердяев верит в существование меона, испускающего свободу и породившего Бога. Бог же создал сей мир и человека по своему образу и подобию. Свобода человека не от Бога, а от меона. И Бог желает, чтобы из этой свободы человек творил новый мир.
Созидание нового мира не есть лишь создание идеальных произведений искусства и науки. Это сверхлюбовь ко всему космосу, созерцание всего одухотворенным, включая неодушевлённые предметы. Созидание нового мира — это проявление сверхдобра, то есть преодоление посюстороннего различения добра и зла, при котором борьба за добро легко обращается во зло. Это отказ от желания судить грешников и создавать для них Ад на этом или ином свете. Созидание нового мира — это обнаружение своих даров (способностей) и подвижническое их развитие и дарение людям, несмотря на необходимость потом и кровью зарабатывать хлеб насущный.
Человек же может распорядиться меонической свободой регрессивно в силу неблагоприятных обстоятельств. Будучи не в силах созидать новый мир, он в отместку может разрушать мир сей. На протяжении истории для большинства людей преобладали неблагоприятные обстоятельства, и от недостатка интуиции формировалось перекошенное, иллюзорное миросозерцание, основанное на статистической видимости.
Миросозерцание Бердяева более глубокое и радостное, чем секуляризованное миросозерцание гуманистов, но оба они закладывают фундамент для преодоления ложных убеждений о человеческой природе.
В этой статье, в отличие от предыдущего доклада, я отказался от слова «гуманистический» в пользу «человечный» в отношении декомпозиции работы, ибо оно точнее, шире и не перегружено смыслом, не относящимся к делу.
«Закон Паркинсона»
Вера в первые 4 ложных убеждения может заставить человека согласиться со следующим утверждением:
Работа заполняет время, отпущенное на неё.
Это «Первый закон Паркинсона», который в 1955 году сформулировал историк Сирил Норткот Паркинсон в сатирической статье на основе наблюдений за британской бюрократией. К сожалению, эта сатира очень быстро распространилась и стала универсальным законом. Даже менеджмент в индустрии программного обеспечения взял его на вооружение, стал тиражировать и бороться с его проявлениями.
В книге «Человеческий фактор. Успешные проекты и команды» Том ДеМарко и Тимоти Листер обосновывают неприменимость этого закона к людям, занимающимся креативной деятельностью, в противоположность серийному промышленному производству и бюрократии. Здесь и далее я ставлю название закона в кавычки, чтобы подчеркнуть отношение к нему как к ложному утверждению в контексте, отличном от описания бюрократии.
Континуум стилей декомпозиции
Стили декомпозиции работы лежат в континууме:
- от микротаскинга, то есть дробления на неделимые атомарные задачи;
- до #NoEstimates, то есть полного отсутствия формального дробления и оценки трудозатрат.
Микротаскинг
Если считать «закон Паркинсона» истинным и соглашаться с ложными убеждениями о человеческой природе, то возникнет понятное желание минимизировать потенциальный ущерб для капитала. Люди такого склада могут прибегнуть к следующим принципам организации производства:
Если человек ленив (ложное убеждение № 2), то задания нужно делать максимально мелкими, чтобы не было возможности ни минуты сфилонить и получить оплату за прокрастинацию.
Если человек не любит людей и общение (ложное убеждение № 6), то всех участников производства нужно обезличить и организовать процесс так, чтобы не требовалось никакого взаимодействия, кроме того, что выражается в коде, документации к нему и тикетах.
Если человеком движет эгоизм и жажда материальных ценностей, то и работодатель и работник должны максимизировать свою выгоду и минимизировать потери. Нужно платить только за сделанные атомарные задания, устанавливая такую цену, чтобы она достаточно удовлетворяла потребности работника и стимулировала его больше работать без прокрастинации, но и без достаточного погружения в смысл. Чтобы делить работу над фичей на мелкие задания по 10—15 минут, нужны некие архитекторы. Они должны обладать авторитетом, и исполнители будут им с радостью подчиняться, ибо испытывают в этом потребность (ложное убеждение № 5).
Это устройство производственного процесса очень напоминает конвейер, на котором рабочие могут выполнять незатейливые, изолированные операции, не требующие ни большой квалификации, ни взаимодействия с другими людьми. Ещё Карл Маркс в 1840-х и Эрих Фромм в 1960-х годах описали такое устройство производства и экономические причины его существования. Также они описали, насколько губительно и невыносимо это для человека. Участвуя в производстве такого характера, человек теряет связь с результатами своего труда, отчуждается от них. Для человека исчезает смысл в его деятельности, он ощущает подавленность и тревогу. Всё это ведёт к раннему профессиональному выгоранию и более тяжёлым последствиям.
Когда все задачи мелкие, то постоянно приходится переключать контекст внимания. Переключение контекста требует от мозга больших энергозатрат (об этом хорошо написано в книге Thinking Fast And Slow). Это огромный источник потерь для смётки. Ослабление смётки приводит к ошибкам. При микротаскинге нет места для восстановления мыслительных ресурсов, или, как это ёмко называет Максим Дорофеев, мыслетоплива. Забота об этом ложится на плечи работника.
К сожалению, мир таков, что достаточное количество людей оказывается искалеченными и им этот производственный процесс подходит. Возможно, он им ближе в сравнении со всем, что они могли испытать на традиционной работе. А заказчики, не избалованные хорошими исполнителями, готовы довольствоваться продуктами, разрабатываемыми в рамках подобного процесса.
Я не могу поверить, что такой подход может приводить к качественным результатам в долгосрочной перспективе. Технический долг и неконсистентность должны неизбежно накапливаться, так что дальнейшее развитие становится тяжким делом. Даже если предположить, что продукты, разработанные по такой системе атомарных задач, получаются приемлемого для заказчиков качества, я не могу не сочувствовать людям, вовлечённым в этот тип производства.
NoEstimates
#NoEstimates (термин возник из хештега в Твиттере) предполагает, что любая фича в продукте разрабатывается быстрее, чем заинтересованные в ней лица успевают спросить про оценку трудозатрат.
Я узнал об этой концепции из доклада Асхата Уразбаева на AgileDays'14. Основными условиями для достижения ситуации, когда не возникает необходимости в оценках, Асхат называет следующие:
- Непрерывная доставка ценности заказчику.
- Отсутствие зависимостей, которые могут что-то сломать. Для обеспечения этого свойства нужен налаженный процесс непрерывной интеграции (CI) с междукомандными интеграционными тестами.
- Уравновешивание возможностей, то есть пропускной способности команды, и потребностей заказчика.
Будучи под влиянием доклада и своего опыта, я пришёл к более строгим критериям, необходимым для работы без оценок:
- Должны использоваться выдающиеся, не мейнстримовые технологии, дающие радикальный прирост продуктивности.
- Команды должны состоять из небольшого числа самомотивированных и высокопродуктивных профессионалов.
- Продукт должен сильно вовлекать своих воплотителей, чтобы они сами предугадывали нужные фичи или реализовывали запрошенную стейкхолдерами функциональность за меньшее время, чем отнял бы процесс оценки и планирования.
Возможно, условий, названных Асхатом, будет достаточно и я слишком требователен.
Ситуация #NoEstimates максимально благоприятна для людей. К сожалению, она встречается редко и может длиться недолго. Например, до тех пор, пока крупный игрок на рынке не купит бизнес и не заменит эту культуру своей.
Всем, кто не входит в число счастливчиков, использующих #NoEstimates, нужно искать способ декомпозиции и оценок трудозатрат, который будет способствовать принятию удачных решений при реализации и не будет оказывать морального давления на исполнителей.
Человечная декомпозиция
В континууме между микротаскингом и #NoEstimates лежит бесконечное множество стилей декомпозиции.
Кажется, мне удалось нащупать золотую середину и очертить стиль декомпозиции, подходящий людям творческим, неравнодушным к своему делу и своим коллегам, занятым в производственном процессе. Я назвал это человечной декомпозицией.
Свойства человечной декомпозиции
При человечной декомпозиции каждая задача удовлетворяет следующим критериям:
- Задача самодостаточна и целостна. Не должно быть аспектов в других задачах, которые могли бы ключевым образом повлиять на создаваемый образ решения данной задачи в голове.
- Задача не превышает 3—5 дней в предварительной оценке трудозатрат. Это ограничение позволит придать задаче обозримые границы и сделает её управляемой, помещающейся в голове.
Вся совокупность задач должна соответствовать архитектурному принципу Loose Coupling / High Cohesion (Слабая зависимость / Сильная сплочённость), а именно:
Loose Coupling: Зависимости между задачами должны быть минимальными.
High Cohesion: каждая задача должна содержать сильно сплочённые функциональные возможности, чтобы ничего нельзя было выбросить без потери целостности размышлений о задаче.
Я заметил, что зависимости через модели и поля в БД гораздо лучше, чем зависимости по API сервисных объектов. Объясняю это тем, что проектирование изменений в БД производится тщательнее, поэтому, когда принято решение, вероятность его изменения низка.
Зависеть же от ещё не разработанных сервисных объектов крайне дискомфортно. Я бы советовал рассматривать зависимости между задачами по API сервисных объектов как decomposition smell (термин аналогичен code smell), то есть маркер низкого качества декомпозиции.
Верификация декомпозиции
Попытаться прийти к декомпозиции с такими свойствами можно итеративно, верифицируя получившийся набор задач. С проверкой помогут контрольные вопросы к отдельным задачам и набору в целом.
Контрольные вопросы к каждой задаче:
- Можно ли целостно думать о задаче в изоляции от других задач?
- Можно ли вынести из задачи что-то лишнее так, чтобы при этом не нарушилась целостность?
- Не слишком ли мала задача? Не должна ли она быть частью какой-то большей задачи, чтобы та была целостной?
Контрольные вопросы к совокупности задач:
- Нет ли между задачами слишком сильных зависимостей, возможно, неявных, в особенности если они даются разным исполнителям?
- Являются ли все задачи управляемыми по объёму (оценка не превышает 3—5 дней)?
- Не слишком ли мелко разбиты задачи и не нарушена ли их целостность?
Вопросы кажутся похожими, некоторые отличаются только объектом направленности. Так и есть. Но в процессе декомпозиции удобно переключаться между режимами анализа каждой задачи в отдельности и всей совокупности в целом. Найденные возможности улучшения при ответе на каждый вопрос порождают новую итерацию. На определённой итерации идеи улучшений заканчиваются и полученная совокупность задач с большой вероятностью будет обладать свойствами человечной декомпозиции.
Обоснование выбранной цифры для границы размеров задач
3—5 дней — цифра условная. Граница размера задачи, которая помещается в голове, будет зависеть от сложности технологии. Данную цифру я привожу для проекта на Ruby on Rails.
Как ни парадоксально, но какое-либо ограничение по трудозатратам не только давит на исполнителя, но и помогает направлять мыслительный процесс при декомпозиции, помогает фокусироваться.
Многих такая большая цифра может тревожить, если они склонны соглашаться c «законом Паркинсона». Я встречал два вида опасений, связанных с этим законом:
- Человек будет прокрастинировать (ложное убеждение № 2) всё время, которое ему выделят на работу, и под конец срока в авральном режиме сделает халтурное решение.
- Человек быстро сделает всё, что нужно, но так как ещё остаётся время, то он из перфекционизма (ложное убеждение № 3) будет заниматься ненужными улучшениями решения вместо того, чтобы перейти к следующей задаче.
При склонности опасаться первого пункта, руководитель может начать следить за скоростью приращения программного кода. Почти всегда чем ближе к окончанию срока задачи, тем быстрее прирастает код, тем больше вносится изменений. Это можно ошибочно принять за доказательство справедливости утверждения о лени человека. На самом же деле это объясняется тем, что чем ближе к окончанию срока, тем ниже неопределённость, тем больше готового кода и понимания, как его улучшить, чтобы довести до образцового состояния. В начале работы из-за большой неопределённости нужно много размышлять, писать в блокноте, проектировать. В том числе нужно прокрастинировать, то есть заниматься отвлечённой деятельностью вдали от компьютера, чтобы мозг в фоновом режиме мог сформировать образ решения.
Большие сроки на выполнение одной задачи требуют доверия к исполнителю. Важно понимать, что люди хиреют при отсутствии доверия к ним, а при наличии — расцветают. Могут быть и исключения, когда люди садятся на шею, но это патология, и будет ошибкой принимать её за правило. Нужно верить, что человек имеет потребность создавать ценности, быть полезным и в нормальном своём состоянии не будет вредить. Человек чувствует себя подавленным, если ему не удаётся уложиться в сроки или когда у него что-то не получается. В этой ситуации важно иметь регулярную обратную связь, чтобы вовремя обнаружить затруднения и поддержать.
При склонности опасаться второго пункта, руководитель может начать пытаться защититься от перфекционизма с помощью искусственно заниженных сроков, таких, чтобы вздохнуть было некогда, не то что сделать что-то избыточное по задаче.
Необоснованный перфекционизм чаще встречается у сотрудников с небольшим опытом. Они ещё не научились мыслить категориями ценности для бизнеса, но имеют потребность показать себя. Здесь продуктивным решением будет частая синхронизация с командой или наставником.
Примеры нарушения целостности задач и ощущения исполнителей
Приведу наиболее яркие и распространенные примеры нарушения целостности задач из своей практики.
Разделение работы над моделью и кодом, её использующим
Предположим, что реализуемая фича требует наличия сущности с персистентным хранением (модель в терминах Ruby on Rails) и CRUD пользовательского интерфейса для неё.
Напрашивающимся решением по декомпозиции будет завести задачу на реализацию модели и на реализацию пользовательского интерфейса, её использующего.
Но думать о модели без учёта использующей её части — это нарушение целостности. Могут получиться неудачные названия полей, типы данных, валидации. Можно не выполнить какое-нибудь требование технологии пользовательского интерфейса, накладывающее ограничения на модель. Или можно сделать модель такой, что код пользовательского интерфейса будет сложнее, чем мог бы, если бы его брали в расчёт сразу.
В Ruby on Rails удобно делать группу чекбоксов для множественного выбора через связь «многие-ко-многим». Это так называемая has_and_belongs_to_many
HABTM-связь между двумя моделями без отдельной модели для связующей таблицы.
Если рассматривать модель без учёта пользовательского интерфейса, то все знают, что HABTM-связь использовать не рекомендуется.
Она выбрасывает модель связи, у которой могут появиться свои поля и поведение. Считается, что проектировщик может срезать углы, используя HABTM-связь, потому что не хочет задумываться о связующей модели как о сущности, имеющей собственную идентичность и состояние. Никто не хочет использовать нерекомендуемые приёмы. Но ситуация, когда связь нужна исключительно для выражения множественного выбора в веб UI, является исключением из правила. В этом случае искусственное введение связующей модели будет перебором и нарушением принципа «Бритва Оккама», то есть внесением сущностей сверх необходимого для объяснения явления или его моделирования.
Если работать и над моделью, и над веб UI, её использующим, в рамках одной задачи, то вовремя заметишь, что связь нужна только для создания группы чекбоксов, а отдельная модель для связующей таблицы — это перебор, и исправишь это.
На ревью кода коллегам сразу будут видны и модель, и код пользовательского интерфейса, её использующий, будет очевидно большинство принятых решений.
Может показаться, что если следовать этому правилу, то задачи будут слишком большими по оценке трудозатрат. Можно попробовать заводить две задачи. Одну — для реализации основного поведения, а вторую — для второстепенных улучшений, про которые сразу не подумаешь. Хотя если менеджмент понимающий, то я бы рекомендовал заводить крупные целостные задачи и не пользоваться этим советом.
Разделение внутри алгоритма
Рассмотрим пример фичи:
- Есть два множества строк.
- Первое множество влияет на состояние элементов второго множества, если элементы второго множества включают или не включают хотя бы один элемент из первого множества как подстроку.
- При любом изменении в первом множестве строк должно пересчитываться состояние элементов второго множества.
- При любом изменении в элементах второго множества, которые являются мутабельными, тоже должно пересчитываться состояние этих элементов.
- Всё усложняется тем фактом, что первое множество строится из нескольких источников и зависит от изменений в этих источниках.
- После пересчёта должна произойти выгрузка обновлённых состояний для другой системы.
Если для такой задачи делать человечную декомпозицию, то можно выделить основную задачу одному человеку на 5 дней, а вспомогательные задачи небольшого объёма дать коллегам, чтобы разгрузить голову основного исполнителя. Если же исходить из того, что люди ленивые и дата релиза уже назначена, то нужно «подстраховаться»: разбить весь объём работ на небольшие задачи менее двух дней в объёме трудозатрат и раздать двум доступным разработчикам.
Между кусками работы этих разработчиков будет много зависимостей. Один разработчик будет создавать узкоспециализированный сервисный объект, который должен будет использовать другой. До начала разработки они должны предугадать подходящий API и потом рассчитывать, что он не изменится, чтобы не подкинуть друг другу лишней работы. Принятый ими API не может быть достаточно хорошо продуман, ибо в этой ситуации некому думать об алгоритме целостно. В нём гарантированно будут ошибки, и он будет оказывать давление на психику исполнителей.
С горем пополам разработчики реализуют свои части мозаики алгоритма. С чувством уверенности, что они сделали свои части работы хорошо, даже автотесты проходят, они выкатятся на ручное тестирование. Хорошо, если ручные тестировщики есть в команде.
И тут выяснится, что только 10% сценариев использования работают корректно, а именно: при добавлении строки в первое множество происходит изменение состояния во втором множестве, при удалении же ничего не происходит.
Винить в этом разработчиков было бы несправедливо. Ни у одного из них не могло быть в голове целостной картины, ибо поставленные им задачи имели узкие границы, конкретные постановки и сроки без запаса по времени, а сроки срывать никто не любит. У них не было и достаточно политического веса, чтобы сказать, что по такой декомпозиции невозможно сделать работу качественно. Заранее можно иметь лишь интуитивное и смутное ощущение неправильности декомпозиции. Важным маркером здесь является наличие зависимостей между разработчиками по API сервисных объектов, но как это доказать в моменте, совершенно неочевидно.
Эта история из жизни позволила ретроспективно выявить проблемы и формализовать интуитивные действия при декомпозиции, которые мне удалось сформировать за годы работы.
Стратегии декомпозиции
Рассмотрим, какие стратегии помогут с небольшим количеством итераций приходить к человечной декомпозиции.
1. Отказ от декомпозиции
Если слово «декомпозиция» воспринимать буквально как разделение на части, то может показаться, что на выходе этого процесса должно обязательно получаться больше одной задачи.
Одна задача, даже большая, вполне может быть результатом процесса декомпозиции.
Если фича недостаточно велика и верхнеуровнево оценена в 3—5 дней, то может так случаться, что дальнейшее деление не даст преимуществ, но может создать проблемы, если ошибиться в границах задач. В особенности, если дать их разным исполнителям в надежде выполнить работу быстрее.
2. Делегирование исполнителю
У тимлида может сложиться ложное впечатление, что в его обязанности входит выполнение всех декомпозиций и спуск задач сверху членам команды разработки. Так может случиться, если в должностной инструкции не донести мысль, что от тимлида требуется обеспечить процесс декомпозиции, а не выполнить её самому. Ещё это впечатление может сложиться из ложного убеждения № 5, что человек нуждается в подчинении и чтобы ему подчинялись. Если же постановку задач делегировать их исполнителю, то никакой власти у тимлида не останется, никакого авторитета не будет и подчиняться ему как следует не смогут, при том что нуждаются в этом.
Тимлиду может даже казаться, что декомпозиция работы — это его основная обязанность, за которую его ценят. Или может казаться, что проще самому декомпозировать и требовать выполнения получившихся задач, чем помогать делать это другим. Эта иллюзия подкрепляется ложным убеждением № 6, что человек стремится избегать взаимодействия с людьми из-за мизантропии. Кажется, что проще спустить сверху готовое задание исполнителю, а не помочь ему сформировать это задание самостоятельно, исходя из понимания требований самим исполнителем.
На самом же деле декомпозиция работы для других людей — это крайне отчуждённая деятельность, которая выматывает и никогда не приносит удовлетворения. К тому же она имеет тенденцию превращать тимлида в «бутылочное горлышко» команды.
Если же декомпозицию делегировать, то у тимлида освобождается время для более творческой деятельности по стратегическому развитию продукта.
Тимлид может заниматься поиском инноваций и воплощением их в спокойном режиме вне критического пути создания ценности, непосредственно необходимой заказчику. Именно так произошло с тимлидом команды, к которой я принадлежу — тут я описываю настоящий опыт.
Таким образом, лучшим решением будет выбор главного исполнителя для реализации фичи и делегирование ему процесса декомпозиции. У главного исполнителя будет максимальная мотивация разобраться в требованиях и обеспечить себе и коллегам задачи с комфортными формулировками и оценками трудозатрат.
Лично я не могу приступить к написанию кода, пока у меня в голове не сложится приблизительный образ решения. Чтобы он сложился, необходимо точно знать, какую проблему и для кого нужно решить. Без этого мозг отказывается работать над задачей.
Если, напротив, меня поставят перед фактом назначенных мне конкретных задач с жёсткими требованиями по реализации и спущенными сверху оценками, то я оказываюсь демотивирован и ощущаю подавленность.
Можно возразить, что есть много разработчиков, предпочитающих работать по чётко сформулированным детальным требованиям, когда им говорят, что конкретно делать. Так и есть. Важно знать своих коллег и их предрасположенности. Таким сотрудникам я бы рекомендовал поручать второстепенные механизмы, требования к которым, как правило, более понятны и могут быть сформулированы заранее с достаточной точностью. Об этом далее в пункте 6 про выделение смыслового ядра.
3. Отказ от детального проектирования
Может сложиться убеждение, что для осуществления декомпозиции необходимо провести детальное проектирование или даже что декомпозиция и детальное проектирование — это одно и то же. Мне кажется, что декомпозиция всё-таки ближе к предварительному проектированию. Производя декомпозицию, лучше всё время оставаться как можно выше уровней реализации и проектирования — где-то между уровнем бизнес-требований и системных требований.
Удобно представлять себе весь объём функциональности как кусок мрамора. От него нужно отделять крупные части, границы которых очевидны уже во время предварительного проектирования.
Может помочь и такой приём: в воображении посмотреть на решение через прищуренные глаза. При этом картинка расплывчата, но различаются силуэты и границы подсистем.
Если произвести детальное проектирование во время декомпозиции, неизбежны ошибки и низкое качество. Ещё сильнее возрастают риски, если задачи будут делегированы голове, отличной от головы декомпозирующего. В результате исполнитель будет парализован в возможности вовремя распознать ошибки, допущенные уровнем выше, и тем более не сможет их исправить.
4. Группировка функциональности по сходному уровню сложности, неопределённости или риска
При планировании и оценке трудозатрат удобно разделять задачи по уровню сложности, неопределённости и риска. В зависимости от характера продукта может подойти разное количество баллов для оценки.
Допустим, получился вариант разделения на задачи и кажется, что он оставляет желать лучшего, но не понятно, как его улучшить. В этой ситуации нужно попробовать оценить, содержит ли каждая задача внутри себя вещи, сходные по уровню сложности, неопределённости или риска.
Если внутри задачи есть пункты с разными уровнями по этим свойствам, то с такой задачей можно застрять, при том что некоторые части уже готовы и их можно было бы продвинуть по конвейеру создания ценности. Это увеличивает объем незавершённой работы — W.I.P. (work in progress). Эмоциональное самочувствие исполнителя ухудшается, потому что на него давит этот незавершённый гештальт.
5. Поэтапная декомпозиция
Иногда бизнес приходит с очень большими фичами или наборами связанных фич, которые для бизнеса важны целиком, а не по частям.
В этом случае нужно разделить работу над этим большим набором фич по нескольким этапам, релизам, спринтам. Частично готовую функциональность можно выкатывать на продакшн, но скрывать за фича-флагами или за авторизацией, чтобы бизнес-пользователи их не видели.
Не нужно обеспечивать декомпозицию сразу по всем этапам. Нужно откладывать процесс декомпозиции до последнего момента, когда её уже необходимо сделать, чтобы коллектив не простаивал.
К этому моменту будет собрана максимально возможная информация для принятия решений и распределения работы по исполнителям. Бережливое производство учит откладывать момент принятия важных решений до последнего момента.
6. Выделение смыслового ядра
Часто в бизнес-фиче можно выделить смысловое ядро и второстепенные механизмы.
Например, смысловое ядро представляет собой алгоритм вычисления чего-либо, а второстепенный механизм осуществляет рассылку результатов вычисления на почту или поставляет их в точку интеграции с другой системой.
Эти концепты я почерпнул из главы 15 «Дистилляция» книги Эрика Эванса «Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем». Для простоты рассуждений я объединил неспециализированные подобласти (Generic Subdomains) и связные механизмы (Cohesive Mechanisms), от которых очищается смысловое ядро (Core Domain), в категорию второстепенных механизмов.
Смысловое ядро всегда содержит больше сложности, неопределённости и риска, а второстепенные механизмы часто бывают более понятны, и границы их хорошо видны на этапе предварительного проектирования.
Хорошим решением может быть поручить смысловое ядро основному исполнителю по этой бизнес-фиче, а второстепенные механизмы отдать его помощникам. Таким образом, основной исполнитель освобождает свою голову от второстепенных деталей, снижается давление на него. Риск не уложиться в сроки релиза снижается.
Эта стратегия очень похожа на метафору хирургической бригады Фреда Брукса из книги «Мифический человеко-месяц».
Автор рекомендует назначать хирургом самого продуктивного программиста, а ассистентами менее продуктивных коллег с меньшим опытом.
Во времена, которые описывает Фред Брукс, системы были больше и обладали огромной случайной сложностью (accidental complexity) из-за неразвитости технологий и железа. Фичи были огромными, а итерации очень длинными.
Но стоит пойти дальше, ведь сейчас типичные бизнес-приложения разрабатываются небольшими приращениями, укладывающимися в итерации длиной от двух до четырёх недель. Технологии скрывают значительную часть сложности за абстракциями. Особенно в этом преуспевают omakase-фреймворки, в частности Ruby On Rails и подобные ему.
При этом есть огромный дефицит разработчиков на рынке, который только возрастает. Для компаний становится стратегически важно ускоренно выращивать младших сотрудников в средних и старших. Исходя из этой стратегии развития людей, стоит стараться чаще назначать хирургом не самого старшего, а самого младшего разработчика в команде и оказывать ему усиленную поддержку. Он будет вникать в фичу от уровня требований через декомпозицию с поддержкой наставника. Будучи максимально вовлечённым, младший разработчик будет ощущать драйв, осмысленность своей деятельности и быстрее расти.
Уже полтора года мы стараемся поступать таким образом, и опыт этот весьма результативный и благодатный.
В команде может оказаться добротный разработчик, отлично справляющийся с работой по чётким требованиям, но не желающий расти подобным образом. Ему можно поручать задачи по второстепенным механизмам, когда их декомпозирует хирург данной фичи. Других же разработчиков нужно назначать хирургами как можно чаще.
7. Выделение прототипа
Выделенное смысловое ядро может оказаться достаточно большим и неуправляемым по трудозатратам. Может быть не очевидным, как его разделить на подзадачи управляемого размера. В этом случае может выручить прототипирование. Стоит взять верхнеуровневую оценку трудозатрат на фичу и часть этого времени выделить на создание прототипа, а остальное время на продуктовую версию.
Можно поделить в пропорции «золотого сечения», когда меньшая часть времени отдаётся на прототип, можно поделить и в отношении 1:3. Но важно выделять на прототип достаточно времени, чтобы не ощущалось чрезмерное давление. Лучше по факту закончить прототипирование чуть раньше — тогда больше времени останется на продуктовую версию.
Как результат создания прототипа появится достаточно информации для разделения работы на задачи, выявления смыслового ядра и второстепенных механизмов, которые можно делегировать другим людям.
Прототип — это тренировочная версия фичи, целью которой является обкатка решений проектирования.
При разработке прототипа допускается снижение стандартов качества, чтобы уменьшить давление на разработчиков и немного сэкономить время. Например, можно не покрывать тестами побочные сценарии. Можно даже не разрабатывать через тесты, если это не оправдано в рамках проверки идеи. Можно не заботиться о логировании, обработке ошибок и надёжности.
Важно понимать и донести это до менеджмента, что ни в коем случае нельзя брать прототип как есть и дорабатывать его до продуктового состояния, как бы ни был велик соблазн.
Продуктовую версию следует разрабатывать с нуля в соответствии со всеми принятыми практиками и дисциплинами, на прототип же лишь посматривать для следования очертаниям решения. Главный эффект от прототипа — это формирование образа решения в голове и отбрасывание ошибочных предположений об алгоритме.
Когда нужно разработать какую-то фичу, обладающую достаточной новизной в системе, ощущается огромное давление. Нужно разработать всё сразу и не ниже уровня своего внутреннего стандарта. Это чувство парализует мозг и вгоняет в жёсткую прокрастинацию. Нужно дать возможность мозгу поэкспериментировать в более лёгкой, игровой форме, не требуя образцовых результатов.
Практика создания прототипов подробно описана в книге Дейва Томаса и Энди Ханта «Программист прагматик. Путь от подмастерья к мастеру» в 1999 году. Ещё раньше, в 1975 году, Фред Брукс описал подобную практику создания опытных систем в книге «Мифический человеко-месяц».
Приведу яркую цитату из Главы 11 «Планируйте на выброс» для тех, кто скептически относится к прототипам:
Поэтому планируйте выбросить первую версию — вам всё равно придётся это сделать.
От прецедента к должностной инструкции
У меня есть убеждение, что вместо стремления к недостижимому идеалу необходимо бороться за уменьшение степени несовершенства и боли. Для меня самым масштабным достижением на этом пути стало формулирование идей человечной декомпозиции.
Уже полтора года мы в команде осознанно применяем обозначенные в статье приёмы. Это дало тимлиду возможность не заниматься постоянно декомпозицией работы для других, а производить инновации: существенно улучшить архитектуру работы с логами, мониторингом и многими другими общими инфраструктурными механизмами. Тимлид смог поучаствовать в качестве основного разработчика в создании нескольких бизнес-фич. Младший разработчик смог сделать то же самое. Он получил драйв, самостоятельность и в результате вырос до мидла. Я сам стал работать ещё комфортнее, чем до изменений. Другие команды стали применять человечную декомпозицию и рассказали мне о положительном опыте.
Моя инструкция по человечной декомпозиции стала в FunBox частью должностных инструкций и отстаивается техническим руководством перед менеджментом в случае недопонимания.
Надеюсь, стремление к человечной декомпозиции поможет всем нам попасть в мир, в котором больше компаний с развитой инженерной культурой и продуктами, обладающими большей концептуальной целостностью.
Источники
Прийти к идеям человечной декомпозиции мне помогли следующие книги:
- Дейв Томас и Энди Хант «Программист прагматик. Путь от подмастерья к мастеру».
- Фред Брукс «Мифический человеко-месяц».
- Эрик Эванс «Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем».
- Том ДеМарко и Тимоти Листер «Человеческий фактор. Успешные проекты и команды».
- Мери и Том Поппендик «Бережливое производство программного обеспечения. От идеи до прибыли».
Найти более глубокое обоснование идеям человечной декомпозиции и опровергнуть заблуждения о человеческой природе мне помогли эти книги:
- Все книги Эриха Фромма.
- Николай Бердяев «Смысл творчества. Опыт оправдания человека» и «О назначении человека. Опыт парадоксальной этики».
- Кен Уилбер «Благодать и стойкость. Духовность и исцеление в истории жизни и смерти Трейи Киллам Уилбер».
- Даниэль Каннеман Thinking Fast And Slow.
- Роберт Пёрсиг «Дзен и искусство ухода за мотоциклом», в особенности рассуждения автора о смётке и вещах, которые её истощают. Я и само это слово узнал из книги.
Направления дальнейшего моего поиска:
- Клер Уильям Грейвз «Спиральная динамика». Первый раз услышал о спиральной динамике от Максима Цепкова на конференции AgileDays'14, кстати, тогда же, когда и про #NoEstimates. Это знание сильно повлияло на меня.
- Кен Уилбер «Интегральный подход». У Уилбера много книг. Я только начал их изучение но кажется, его миросозерцание созвучно Николаю Бердяеву и потому интересно, до каких озарений дошёл современный нам человек, интересующийся широким спектром вопросов философии, психологии, духовности и науки.
Changelog
UPDATE 2020-10-27 Уточнение формулировки понятия о ложности убеждений о человеческой природе
Благодаря комментариям @JustDont
и @iiopy4uk_msk
мне удалось улучшить формулировку моего утверждения о ложности растиражированных убеждений о человеческой природе. А именно проблема возникает, когда описанные частные случаи поведения считаются общезначимыми свойствами человеческой природы, и от этого выстраивается априорная защита даже в креативных видах бизнеса. Это же относится и к «закону Паркинсона», согласие с которым может вытекать из данного обобщения.
UPDATE 2020-10-27 Добавление описания контекста, в котором выкристализовались идеи
После опубликования статьи я стал смотреть, что ещё пишут про декомпозицию, и оказалось, что она бывает на разных уровнях. Есть декомпозиция уровня бизнес-анализа, когда выясняется какие есть у бизнес проблемы и как их разбить на независимые фичи. А есть декомпозиция уровня разработки, когда уже от уровня бизнес-анализа поступили разумные готовые истории на разработку. При этом не исключается, что на уровне разработки станет понятно, что эти требования нужно вернуть на доработку аналитикам. Статья фокусируется на проблеме декомпозиции работы по реализуемым разумным требованиям.
Так же @iiopy4uk_msk
указал на полезность обозначения контекста для лучшего понимания подхода. Эти размышления привели к добавлению раздела Контекст. В нём я привёл описание типа продукта, типичной фичи, состава команды разработчиков и её отношений с внешним миром.
sshikov
Ну, хорошие принципы, без дураков. Тут есть только одно но: критерии эти недостаточно конструктивны. То есть, они не позволяют построить декомпозицию, чтобы она сразу была такой как надо. В том числе потому, что у этой задачи нет единственно правильного решения, да и критерии недостаточно четкие (циферки для измерения самодостаточности есть? а нету).
Ну например, задача самодостаточна и целостна. Ну ок, про одну задачу мы это знаем. А про все решение в целом? Достаточно типовой проблемой декомпозиции является та, что человеку свойственно забывать некоторые части решения, необходимые для его функционирования. Особенно — для задач нетиповых, какие вы никогда не решали.
Я для себя сформулировал немного другой человеческий принцип — единственное, что помогает не ошибаться (в том числе при декомпозиции) — это твоя квалификация (или квалификация команды). То есть надо набирать умных людей, а тех кто есть — учить. И учиться.
alexpetrov_rb Автор
Благодарю за положительный отзыв, sshikov.
То о чём Вы говорите, это не принципы, а свойства человечной декомпозиции, к которым нужно стремиться. В следующем разделе «Верефикация декомпозиции» я добавляю конструктива. Я пишу о том, как итеративно с помощью контрольных вопросов к каждой задаче, и ко всей совокупности задач, можно достигнуть декомпозиции, которая будет иметь шансы на обладание таким качеством. А в разделе «Стратегии декомпозиции» я даю рецепты, как сделать это с меньшим количеством итераций и с чего начать.
Прошу Вас уточнить критику, если и в этих разделах конструктива окажется недостаточно. Это поможет улучшить статью.
Насчет квалификации и обучения, полностью согласен. Именно это мы и стараемся делать, пользуясь стратегией назначения главным исполнителем по некоторым фичам самого младшего разработчика в команде, делегируя ему процесс декомпозиции и оказывая ему поддержку со стороны умных, как Вы говорите, людей. Когда удаётся это делать — это самый благодатный опыт для меня!
sshikov
Я так понял, будет продолжение?
alexpetrov_rb Автор
Статья задумана как самодостаточная и не предполагает продолжения. Хотя обратная связь может привести к идеям развития.
У меня возникла мысль о написании выжимки из статьи с сокращением количества рассуждений. Только голые советы, просто для шпаргалки.
Правильно я понимаю, что у Вас есть впечатление, что конструктива в статье недостаточно, либо что он погребен под объёмом текста и до него сложно добраться?
sshikov
Да, есть такое. Выводы можно бы и обобщить в краткой форме.
alexpetrov_rb Автор
Спасибо, Сергей!
Постараюсь сделать шпаргалку.
Пока в качестве выжимки предлагаю часть текста презентации предыдущего доклада: github.com/alexpetrov/humanistic-work-decomposition#%D0%B3%D1%83%D0%BC%D0%B0%D0%BD%D0%B8%D1%81%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F-%D0%B4%D0%B5%D0%BA%D0%BE%D0%BC%D0%BF%D0%BE%D0%B7%D0%B8%D1%86%D0%B8%D1%8F