Главное — хвост. Технология конвейеризации разработки программного обеспечения

    Написано в сотрудничестве с Ревазом Бухрадзе (редактор: Ангелина Кипелова)


    Технология тем и отличается от кустарного производства, что результаты повторимы, а сроки их достижения прогнозируемы, также и в любой науке результаты эксперимента признаются только в случае, если их удалось повторить (а еще лучше – поставить на поток). И её смысл заключается в том, чтобы успешно воспроизводить алгоритм работы каждый раз, когда это нужно. Например (это как раз плохой пример) китайские типографии печатают каталоги и упаковки дешево, но за ними нужен глаз да глаз. Сегодня они использовали выданные заказчиком настройки, а завтра решили, что они знают, какие подешевле лучше цвета использовать. И, скажем, вместо черно-желтых полосок Билайн может обрести красно-синий колер. А восточная бригада рабочих, оставленная без присмотра в процессе кладки кирпичной стены, может изобразить инсталляцию «бегущая волна» при помощи подручных стройматериалов. То есть, смысл технологичности в том, чтобы система работала автономно, и результат на выходе каждый раз был одинаково удачным. Ну за редким неизбежным исключением.


    Философский камень универсальной методологии


    Специалисты спорят до кровавых холиваров, какая модель производства ПО лучше, и когда (какую и для чего) методологию стоит применять в крупных компаниях. Там, где уследить за департаментом разработки невозможно физически, и где любые задержки и критические ошибки чувствительно отражаются на работе гигантской махины. Очень хочется каждому солдату стать генералом специалисту нащупав тот самый «универсальный» метод, который позволит сократить количество проблем в процессе разработки, при этом повысить эффективность до уровня «утритесь, конкуренты!» (однако, как известно — нет серебряных пуль).


    Однако если не определить, что значит это самое «лучшее решение» в каждом определенном случае, то найденные ответы будут похожи на мебель из Икеи: «вот общие рецепты, а дальше все сами». Так же, как и лекарство подбирается индивидуально под ряд параметров (хотя результат стремления везде одинаков – выздоровление), так и методология разработки ПО тоже подразумевает предварительный анализ поля «дано».


    Применение различных моделей разработки ПО: когда и что срабатывает лучше


    • Водопадная модель эффективна, если хорошо определены требования, и за время проекта они сильно меняться не будут. Заказчик не прибежит, помахивая свежим ТЗ, и не плюхнет его на стол с громким заявлением: «Концепция поменялась!». Если срок исполнения не полыхает, а ресурсов хорошей квалификации достаточно для реализации проекта – модель неоспоримо прекрасна.


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


    • Agile – модель, лояльная к отсутствию определенных требований в начале проекта. Выглядит примерно как «Боря! Жарь рыбу!» «Да где та рыба, Степа?» «Боря, ты пока начинай, а рыба будет!». То есть, если требования расплывчаты, и будут появляться, изменяться и переворачиваться с ног на голову.
      Эта модель позволяет реализовывать конечный результат «по частям» с максимально ранним получением работающего продукта, реализующего основной замысел. Требование к этой модели — достаточное количество ресурсов хорошей квалификации, причем существенная часть — широкого профиля. Адаптация к изменению требований должна быть моментальной.

    Есть и другие методологии [1],[2] но приведенные выше считаются основными и достаточно широко используются на практике.


    Почему именно так?


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


    • уровень неопределенности и риски связанные с ошибками на ранних стадиях процесса (сбор и анализ требований, проектирование);
    • наличие и компетентность персонала;
    • время до получения готового результата.

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


    Экономика производства


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


    Процесс Расходы связанные с объемом задачи Расходы связанные с длиной производственного цикла
    Анализ и проектирование (АП) Разработка требований и архитектуры Поддержание документации в целостности
    Разработка и документирование (РД) Разработка, проверка кода и документации и исправление ошибок найденных на этапе тестирования Сборка и поддержание целостности документации
    Тестирование (Т) Функциональное и интеграционное тестирование Регрессионное и нагрузочное тестирование
    Внедрение (В) Сборка, управление дистрибутивами и конфигурациями, развертывание
    Администрирование Планирование и управление ресурсами (в случае agile-ритуалы )
    Управление производственными средами (Dev|Test|Prom), поддержка инструментария и процессов Dev и Ops и т.п.

    Проведем качественное сравнение экономики процессов для водопадной модели и agile, взяв за $X$ — трудозатраты, необходимые для реализации заданного объема функционала, а за $C$ — трудозатраты, связанные с производственным циклом. В этом случае общие трудозатраты составят:


    • для водопадной модели $(1+p)\cdot (X + C)$, здесь $p$ — коэффициент, связанный с объемом доработок, возникающих вследствие изменения исходных требований;
    • для agile — $(1+p)\cdot X + N\cdot C$, где $N$ — количество итераций, необходимых для достижения результата.

    Сравнивая эти результаты, мы получаем следующий вывод:


    • водопадная модель эффективнее agile в случае, если $(1+p) < N$ т. е. объем переработок невелик.
    • при высокой степени неопределенности и высоком риске доработок $(1+p)\ge N$ agile становится эффективнее.

    Также можно заметить, что автоматизация процессов производства (или модный DevOps) существенно повышает экономическую эффективность agile за счет минимизации расходов (связанных с длиной производственного цикла), т. к. этими производственными расходами $C$управлять куда проще, чем желаниями и фантазиями заказчика $p$.


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


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


    Ресурсная загрузка


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


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


    image


    Эти неравномерности требуют от менеджмента плясок с бубнами заметных усилий для соблюдения сроков сдачи проекта. Необходимо минимизировать простои и назвать клиентам реальные сроки исполнения задач. Причем для водопадной модели и для agile (в части спринта), ввиду, того, что этапы внутри соответствующих производственных циклов организованы последовательно, данная проблема с неравномерностью использования стоит острее, чем для моделей итеративного типа. Почему острее, — построим профиль ролей для, например, для waterfall — цикла разработки в 10 недель.


    image


    Теперь предположим, что у нас на подходе есть следующая аналогичная по размерам и сложности задача и нам надо спланировать её оптимальное выполнение. Если не заниматься дефрагментацией загрузки, или как часто шутят «тетрисом», то получится следующая картина, позволяющая при 10-недельном производственном цикле выпускать готовый продукт раз в 7 недель (разрыв между релизами помечен красной стрелкой <=>):


    image


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


    Теперь обратите внимание на серую зону – она достаточно велика, чтобы сделать понятный вывод: расчет не оптимален. Нет здесь равномерной загрузки персонала. Однако после некоторой оптимизации и перепланировки картину можно несколько улучшить: сократить общую длительность проектов на две недели, оптимизировать загрузку персонала, что при таком же 10-недельном цикле позволит выпускать готовый продукт уже раз в 5 недель:


    image


    Проблема конвейера – точно вовремя


    Это только на бумаге получается идеально оптимизировать работу. А де-факто на время планового простоя персонала бывает довольно сложно придумать, чем бы занять ресурсы. В теории – дать полезную загрузку, на соответствующие периоды отдав их, например, в другие проекты. Но для этого нужны проекты, которые реализуются в «кусочках». Что в реальности, скорее, утопия, чем реальная возможность. Большинство проектов требуется сделать «от и до». Поэтому в полноценных периодах, позволяющих добиться результата, зияют дыры, и менеджменту приходится снова и снова заниматься перепланированием. Создавать авралы, периоды переработки и закономерных простоев. Та же проблема, только в меньшем объеме характерна и для итеративного подхода, — достаточно в качестве единицы измерения взять не неделю, а 2-3 рабочих дня.


    Отдельно стоит отметить и то, что это проблема характерна и для agile методологии, причем ввиду краткой длительности спринта (обычно две недели) она еще усугубляется. Чтобы решить сложную задачу, требующую существенной трудоемкости, нужно выйти за пределы трудомощности одного спринта. Следовательно, появляется тот самый «аврал»: увеличивается нагрузка на аналитиков и архитекторов в части разбиения задачи на подзадачи и поддержания целостности результата каждого спринта.


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


    1. иметь разумные затраты на администрирование;
    2. поддерживать высокую степень определенности требований, давая при этом заказчику остаточную свободу фантазии;
    3. обеспечивать существенную трудомощность на каждый производственный цикл, позволяя решать сложные задачи за один этап;
    4. гарантировать регулярный выпуск продукта для того, чтобы иметь возможность оплачивать труд команды;
    5. обеспечивать непрерывную и равномерную загрузку команды.

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


    Причем здесь Kanban?


    Знаменитая японская методология используется не только на заводе по производству автомобилей Toyota. Если применить ее в итеративной разработке, она позволяет при помощи задаваемых ограничений на «работу в производстве» (WIP – work in progress) создать аналог избыточных запасов в производственной модели и синхронизировать относительные объемы работ, выполняемых на различных этапах производственного цикла. Таким образом, минимизируется незавершенное производство. При этом процесс достаточно экономен, в то время как трудомощность на цикл позволительно увеличить. Однако критерии регулярного выпуска и гарантированной загрузки по умолчанию не выполняются.


    Чтобы обеспечить их выполнение, необходимо сравнить производственные циклы сборки машин и производства ПО (картинки найдены в интернете).


    Конвейер Toyota Офис разработки

    Чувствуете разницу?


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


    Тем не менее, систему kanban можно примерить в производстве ПО, если сделать то же самое, настроить конвейер. То есть, определить длительности этапов производственного цикла и стараться выдерживать их.


    Длительность производственного цикла возьмем, равную $16$ неделям, при этом готовый продукт будет появляться раз в $4$ недели, что позволит постепенно «догнать и обогнать» классическую итеративную модель, а именно, если сравнивать длительность производственных циклов в неделях, мы получим $10+5x=16+4x$ откуда получаем $x=6$, т.е. на седьмом производственном цикле мы уже будем получать эффект.


    image


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


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


    Для этого сначала введем единицу измерения доступной трудуомощности – пусть это будет «квадратик» или кв. Данная единица соответствует объему, который может сделать команда из $n$ человек в течение недели. Тогда балансировка должна проводиться следующим образом:


    • Аналитики и проектировщики — объем доступной трудомощности в итеративной разработке 10 кв., объем эффективной трудомощности 4 кв. соответственно при длине производственного такта в 4 недели необходимо 4 кв. Количество аналитиков и архитекторов, которых надо переориентировать на другие работы, составляет 60% от текущей численности;
    • Разработчики и технические писатели — как при итеративной разработке, так и при конвейерной — по 12 кв., и вся трудомощность эффективная — перебалансировка не требуется;
    • Тестировщики — при итеративной разработка трудомощность 10кв., при эффективной — 7 кв.; при конвейерной — 8 кв. То есть, переориентировать на другие проекты необходимо 20% от текущей численности по роли;
    • Внедренцы — объем доступной трудомощности в итеративной разработке 10 кв., объем эффективной трудомощности 3 кв., при конвейерной разработке — 4 кв., т. е. количество внедренцев, которых надо переориентировать на другие работы, составляет 70% от текущей численности.

    Однако данный подход, как и все в ИТ, не является «серебряной пулей», наповал убивающей монстра сорванных сроков. Да, методология позволяет неплохо решать вопросы, связанные с оптимизацией ресурсного планирования, но по задачам необходимо учитывать риски, напрямую следующие из правил построения конвейера:


    • На этапах анализа и проектирования необходимо учитывать трудомощность, доступную на всех последующих этапах;
    • При конвейерной схеме есть только минимальные возможности для доделок, и доработок и прочих работ по «занесению хвостов». Все то, что не проходит соответствующий этап, вовремя должно быть снято с конвейера, как брак. И эти показатели необходимо учитывать в объеме доработок на следующем такте. В противном случае конвейер рассинхронизируется и тут же потеряет эффективность (а с ней и смысл);
    • Конвейер по своей природе, обеспечивая высокую эффективность, является в некотором смысле потогонной машиной;
    • В отличие от «веселого» подхода aglile, стимулирующего расширение компетенций по всем направлениям команды для обеспечения взаимозаменяемости, конвейер направлен на углубление компетенций и повышение персональных навыков в своей и смежной областях. То есть, разработчик должен более или менее разбираться в архитектуре, чтобы даже и не начинать кодирование по спецификации, которую он считает некачественной.

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


    Выводы


    В общем, прав был дедушка Форд, когда от заказной разработки перешел к конвейерному производству автомобилей, что потом вслед за ним проделали все другие крупные автопроизводители и они — капиталисты не спорили о методе, а использовали то, что эффективнее (хотя надо отметить, что болиды F1 собираются по технологии с элементами agile). Учитывая почти вековой опыт конвейерного производства, однозначно стоит использовать алгоритмы высокотехнологичной отрасли на благо будущих результатов.

    Поделиться публикацией

    Комментарии 7

      +2
      Алексей, скажите, пожалуйста, есть ли у вас опыт участия в реальном проекте по разработке ПО? В т.ч. с использованием тех методологий, которые вы упомянули в статье.
        +1
        День добрый, да с 90х по конец 2000х в основном организация производства софта по классике — с необходимостью перехода в итерации.
          0
          Все в статье очень хорошо. Одно но — вывод — на мой взгляд, переход к примеру с конвейером Форда, не очень уместный. Разработка ПО имеет существенное отличие от материального производства — разово разработанное программное обеспечение почти не требует затрат на тиражирование. Но зачастую имеет существенные затраты на внедрение — которые фактически отсутствуют у результатов конвейерного производства, например автомобилей. С другой стороны конвейер ориентирован на разовые, повторяющие операции, инженерные задачи, существенно отличаются от них.
          Поэтому указанная инновационная модель в виде конвейера — на мой взгляд, все та же модель agile в виде последовательности спринтов, в которой каждому сотруднику дают задачи под его специализацию на весь объем спринта. Т.к. в методологии agile разработки — вовсе нет жесткого требования кустарного/мануфактурного производства всей командой всех видов работ. Да и редко какой разработчик сядет на аналитку, или там инженерную инфраструктуру. По моей практике — в более менее крупных командах (от 5ти человек) — есть эти специализации и они разделены между сотрудниками. Все простои решаются двумя смежными специализациями у сотрудников и периодизацией задач по году. Например у ИТ работающем в гос.секторе январь-февраль время доделки хвостов, март-июнь время продаж и разработки «новых продуктов», июль-ноябрь основной проектной реализации, декабрь — авральных допилов ключевой функциональности под требования закрытия контрактов + модель переработок с двойной компенсацией времени — достаточно мотивирующая и позволяет не набирать избыток специалистов, а работать всегда на неком «дефиците», чему кстати и дефицит ИТ-специалистов способствует.
          У всех остальных — маржинальность разработки в ИТ отрасли пока такова, что можно направлять простаивающих сотрудников на «перспективные свои проекты», на устранение технического долга, переделку архитектуры и платформы, «новые продукты» и т.д. и т.п.
          При этом дефицит ИТ-шников способствует высоким окладам и у них смещается модель мотивации в сторону «интересной, развивающей и разнообразной» работы, а это явно противоречит принципам конвейера.
            0

            День добрый!


            Тут есть два момента организационный и философский.
            Философский очень хорошо описан у Анчарова:


            Главное правило для художника — быть исключением. Хочешь, не хочешь. Такая промышленность.
            Потому что, если я два велосипеда сделаю вместо одного, то это будет — два велосипеда. А если я два раза один и тот же стих напишу, то это будет один стих, а не два. Стих или картину, любое сочинение — все равно. А сколько раз я эту картину изготовлю, сколько штук я этого сочинения изготовлю — это уже значения не имеет. Это называется тираж. Тираж, повторение, репродукция — это есть ремесло. А искусство каждый раз происходит по одному разу.
            Вот в чем особенность, дорогой дядя.

            В общем с этим нельзя не согласиться, что разработчик пишет однократно, но


            • ПО всё ж таки продаётся по модели тиража, а не однократно, т.е. мы либо платим за лицензию, либо аредуем её(оптимизируя налогообложение)
            • Производство искусства в отличие от производства ПО не формирует крупных контор, типа MS, по разработке и производству картин (иначе тираж), единственное — модные дома, но и там тираж и деньги.

            Организационный — здесь в отличии от agile идея в том, что если заранее подумать о том, что включить в такт конвейера не придётся об этом думать потом.

              +1
              Собственно вопрос в том, насколько уместно применять термин и перенос технологии конвейера, решающего задачи тиражирования, к проектированию. Проектирование автомобилей, разве конвейерное производство? Если для технологии разработки ПО, даже массового, притягивать термин конвейера — то это все равно будет совсем другая сущность, и логичнее для неё другой термин и применять.
              Переключение специалистов между разными потоками объектов и циклами разработки — мне не кажется даже близко похожим на выполнение одной и той же рудиментной операции на своем участке. Даже противоположной — здесь мы не разные однотипные объекты подаем одному специалисту на один этап. А одного специалиста на разные типы объектов переключаем и зачастую разные задачи он решает, по специализации.
                0

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


                Сам по себе конвейер нужен для выравнивания нагрузки, переключения же при таком подходе возникают с той частотой которой мы их спланируем, можно чаще, а можно и реже чем agile-спринты. Идея здесь в том, что эффекта с выпуском версии раз в две недели можно добиться не только путём сокращения цикл разработки ПО до двух недель (при этом на продуктивную разработку будет потрачено примерно неделя ), но и конвейеризацией (при этом на разработку будет потрачено уже две недели). Просто большие непрерывные куски времени позволяю решать более сложные задачи, не занимаясь их искусственным дроблением, что иногда полезно (при перекладке математической теории на код, например)


                Что касается рудиментарности операций — то тут как посмотреть:


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

                Т.е. однотипность не в составе работ, а в объёме свободного времени на эту работу.

                  0

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


                  Сам по себе конвейер нужен для выравнивания нагрузки, переключения же при таком подходе возникают с той частотой которой мы их спланируем, можно чаще, а можно и реже чем agile-спринты. Идея здесь в том, что эффекта с выпуском версии раз в две недели можно добиться не только путём сокращения цикл разработки ПО до двух недель (при этом на продуктивную разработку будет потрачено примерно неделя ), но и конвейеризацией (при этом на разработку будет потрачено уже две недели). Просто большие непрерывные куски времени позволяю решать более сложные задачи, не занимаясь их искусственным дроблением, что иногда полезно (при перекладке математической теории на код, например)


                  Что касается рудиментарности операций — то тут как посмотреть:


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

                  Т.е. однотипность не в составе работ, а в объёме свободного времени на эту работу.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое