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

Фагнер Брек считает, что такое происходит потому, что эти проекты не реализовывали принципы непрерывной интеграции. В своей заметке, перевод которой перед вами, он пишет, что в известном ему случае кое-что нужно делать по-другому с самого начала:

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

Но как это сделать? Это фундаментальный вопрос, с которым каждому приходится столкнуть в программном проекте: всё изменится.

Как можно непрерывно интегрировать проект каждый день, если для его завершения требуются месяцы, а не дни?



Если все возможные решения проблемы не приводят к жизнеспособному варианту, единственная альтернатива — изменить вопрос.

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

От переводчика: оригинальная статья посвящена идее Incremental Delivery, которую далее мы будем называть итеративной разработкой, самым тривиальным образом опираясь на википедию, поскольку это не противоречит высказанным в статье идеям. Если же вам больше нравится «инкрементная поставка», то совершить мысленную замену будет нетрудно.

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

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

Но кое-что в этом комиксе не совсем очевидно.

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

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

В итоге, пользователь просто доволен.

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

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

Теперь он счастливее.

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

Есть еще один неочевидный момент.

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

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

Однако, если вы рассматриваете «скорость», как сумму ценности, которую вы получили, то вполне возможно, что вам потребуется больше времени, чтобы сделать что-то, но меньше времени, чтобы закончить это. Хитрость заключается в том, чтобы построить минимальный жизнеспособный кусок, который может сделать пользователя счастливым, даже если это не окончательный «большой проект».

То, что люди хотят, изменится, и первоначальный запрос устареет. Или, как я и говорил раньше — всё изменится.

Единственное, что можно сделать, это принять этот факт с самого начала и строит планы соответственно.

Не пытайтесь изменить мир, плывите в потоке.

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

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

Примечание: вы можете утверждать, что комикс — плохой пример, который не соответствует реальности… и вы правы. В комментариях к оригинальной статье автор дает ответ на такое замечание.

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

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

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

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

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

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

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

Уйдет уйма времени, чтобы сделать что-то работающее.

Или вы можете написать небольшую функцию, которая вернет прибыль от операции покупки/продажи и которую можно запустить в Chrome DevTools.

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

Еще можно добавить пару операторов console.log в качестве замены «тестовой платформы». Этого должно быть достаточно, чтобы убедиться, что функция работает. Вы даже можете построить её с помощью TDD!

function profitFrom({ sell, buy }) {
    const profit = sell - buy;
    return (100 * profit / buy) + '%';
}
console.log(`${profitFrom({ buy: 50, sell: 50 }) === '0%' && 'PASSED' || 'FAILED'}: No profit or loss for break even`);
console.log(`${profitFrom({ buy: 50, sell: 100 }) === '100%' && 'PASSED' || 'FAILED'}: Profit`);
console.log(`${profitFrom({ buy: 100, sell: 50 }) === '-50%' && 'PASSED' || 'FAILED'}: Loss`);

Если вы все же хотите сделать интерфейс получше, вам не нужен сервер. Вы можете создать HTML-файл с несколькими текстовыми входами и запустить его локально из файловой системы.

Если действительно нужно, то запустите статический сервер и просто скопируйте HTML.

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

В эссе "Собор и Базар" рассказывается об использовании итеративной разработки в OpenSource сообществе. Вот выдержка:

Лайнус относился к своим пользователям, как к со-разработчикам, с максимальной эффективностью:

7. Выпускай продукт раньше. Выпускай часто. И слушай своих клиентов.

Этот принцип в конечном итоге нашел свое место в Agile-манифесте в такой форме: «Наивысшим приоритетом является удовлетворение потребностей заказчика, благодаря регулярной и ранней поставке ценного программного обеспечения».

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

Вместо того, чтобы смотреть на решение, посмотрите на проблему. Вместо того, чтобы смотреть на ответ, посмотрите на вопрос.

Как инженеры, мы склонны понимать прогресс как результат упорного труда. Однако нам нужно работать с умом.

А это означает, что надо меньше программировать и думать более инкрементально.

Убедитесь, что вы не начинаете с не того колеса… или упустите свой шанс.

Если так вас гложут сомнения, насчет правильности выбора колеса, рекомендуем профессиональные конференции для тех, кто делает интернет РИТ++ 2018. Во-первых, это масса ценной информации, можно сказать на блюдечке, во-вторых, дискуссионные зоны и митапы, в-третьих — съезд активистов, и просто около 2000 человек, среди которых обязательно найдутся те, с кем можно обсудить именно ваши проблемы.

Комментарии (13)


  1. poxvuibr
    17.04.2018 11:58

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


    1. lxgdark
      17.04.2018 12:08

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


      1. poxvuibr
        17.04.2018 13:35

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

        То есть мотоцикл это концептуально тот же продукт, что и автомобиль, а автомобиль это просто мотоцикл, доведённый до идеала? И промежуточных этапов между ними не должно быть?


        1. samsdemon
          17.04.2018 15:58
          +11

          image


        1. lxgdark
          17.04.2018 18:43
          +2

          Концептуально пользователь хочет ехать. А скорость и комфорт будут достигнуты с новыми версиями.
          Да картинка от samsdemon лучше показывает суть, но и та, что в посте также с задачей справляет. Главное относится к метафоре, как к метафоре )))


          1. poxvuibr
            17.04.2018 19:33

            Концептуально пользователь хочет ехать.

            Видимо, на картинке из поста в четвёртом этапе надо было рисовать железнодорождый состав. Концептуально проблемы пользователя решены, этапов разработки по прежнему 4, так что картинка с железнодорожным составом справляется со своей задачей не хуже той, что в посте.


          1. hVostt
            17.04.2018 20:54
            -2

            Как пользователь. Я хочу заплатить за полный функционал. За ущербный платить нет желания. Если я иду покупать машину, мне нужно все: колёса, педали, комфорт, подушки безопасности.
            Как разработчик. Разрабатывая продукт, обычно постановка такая: давайте хоть что-нибудь. А после поставки первого варианта, и ввода эксплуатацию ожидания такие: должно работать основное всё. Не может быть такого, что система отчётности показывает отчёты, но не даёт распечатать. Это означает, что продуктом нельзя пользоваться, он не готов.
            Если говорить про фичи, т.е. вещи, расширяющие возможности продукта, добавляющие как те же задачи можно выполнять лучше, проще, удобнее, пушистее, то это тоже к картинке не относится. Это просто развитие продукта.
            CI это не про то, что сделать какой-то полуфабрикат и пустить в эксплуатацию. Это контроль заказчика за исполнением и своевременные корректировки.


            1. D01
              18.04.2018 23:08

              Вам надо перевозить кирпичи вчера. Бюджет зависит от количества перевезенных кирпичей.
              Разве не логично Тачка — Телега — Пикап — Грузовик?
              Иначе простой и нулевой бюджет (даже минусовой, т.к. кушать же что-то надо)..


          1. hVostt
            17.04.2018 21:01
            -2

            Опять таки, смотря что разрабатывать. Давайте делать самолёт, вот с таким подходом? Или медицинское оборудование, м? Быстрее дадим какую-то поделку, а упадёт, да и фиг с ним. Умрёт пациент на столе, да и ладно. Потеряет заказчик деньги, из-за того, что секьюрные данные утекут? Да фигня вопрос. Зато по несколько фич в день! Что же там за фичи такие, которые за день-два делаются?

            Я не буду особо ванговать, если скажу, что речь идёт исключительно о прикладных задачах. Если вы конкретно заморочились и сделали за пол года год, вменяемый фреймворк, учли множество факторов, то да. Потом можно выдавать результат хоть каждый день.

            Если речь идёт про подвинуть картинку на 5 пикселей вправо, а сделайте сюда загрузку файлов, а сюда подсказка пусть вываливается. Ну боже мой, о чём речь?

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


  1. darkAlert
    17.04.2018 13:54

    MVP же? Или я чего-то не понял


  1. hVostt
    17.04.2018 21:08

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


    Меня сама концепция «нужно понравится» удивляет. Судя по статье, основная задача — это понравится пользователю. Значит подход «сделай уродский вырвиглаз дизайн с котиками, который понравится жене заказчика, но не решает никаких задач», это как раз и есть тот самый вектор постановки вопроса? :)


  1. HomunCulus
    17.04.2018 22:22

    Да будут счастливы все те, кто уверен наперед что он знает как оно должно быть. Автомобиль, переднеприводный, мощность до 200 киловатт, дизель, салон кожаный темный, купе, крыша нежесткая. И кому рынок ответит не фи, а да-да-да.
    Пока ты не вышел в прод и не получаешь реальную, еще раз, реальную обратную связь, а не инженерные предположения как оно должно быть, и должно быть ли вообще, можно пилить все что угодно.
    И скорость прогресса, после выхода в прод, получения обратной связи от людей кто будет пользоваться, вырастает в разы. Ну вот реально. кто пробовал, тот знает.
    Но желаю удачи с уверенностью знания наперед. :)
    image


  1. vyatsek
    18.04.2018 01:05

    Мой каммент относится к автору, не к переводчику.
    Опять какой-то теоретический булшит про итеративную разработку без примеров, деталей и конкретики.

    Принцип итеративной разработки можно применить к почти любой области, а не только к той, с которой взаимодействует пользователь.
    Именно, Итеративной разработке уже 100500 лет, видимо современные программисты совсем далеки от пика индустриализации, производства и конструирования. То же семейство оружия Калашникова Михаила Тимофеевича (КМТ), вполне себе результат итеративного подхода.
    В итеративной разработке существует 100500 разных стратегий и подходов. При разработке основная цель это реализовать целевую функцию! И судя по картинке автора, КМТ должен был начать с рогатки, но в реальности это не так. Целевая функция может быть реализована не оптимальна/ не полностью, но так или иначе первый шаг к решению проблемы уже будет сделан.
    Как можно непрерывно интегрировать проект каждый день, если для его завершения требуются месяцы, а не дни?
    Не верно выбрана целевая функция или стратегия реализации. На сегодня сложно найти задачу, которую пришлось бы решать заново. При реализации целевой функции как правило переиспользуют уже существующие технологии и компоненты, жертвуя простотой, скоростью, универсальностью, гибкостью и т.д. но только для того чтобы понять, что реализация целевой функции принесет выгоду.
    Вместо того, чтобы спрашивать «как построить большой проект?», вы должны спросить: «как разделить большой проект таким образом, чтобы я мог построить самый маленький полезный кусок?»
    Чем больше шкаф — тем громче падает. Изначально строить большой проект — утопия. Как пример история Линукса и гита. Линус решал свою узкую задачу, а получилось вон чего.

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