×Закрыть

Технический долг или Право на выбор

Действительно правда, что наше внимание фокусируется сильнее на предметах и явлениях которые ближе к нашим тактическим задачам. Оно, так сказать получает дополнительную «привязку» на такие объекты. Работая над возвращением технического долга, за последние несколько дней увидел множество статей\постов на эту тему. Такое чувство, что только ленивый об этом не писал :). Не буду пересказывать то, что написано здесь и здесь, а сосредоточусь на прикладном аспекте вопроса.

Давайте оттолкнёмся от уже общепринятого термального элемента — спринта.

Обсуждая ту или иную задачу, у Вас есть два пути её решения:

  1. «Quick Win» — чаще предлагается менеджментом, характерен быстрым достижением результата за счёт этого самого технического долга, когда «заплатка» лучше чем дизайн.
  2. «Long way» — в противоположность первому, имеет место быть, когда у Вас достаточно ресурсов и Вы смогли убедить руководство в необходимости прототипирования, UML-ирования и бла, бла, бла :)

Невозможно сформулировать правила на все случаи жизни — где лучше применять первый, а где второй метод. Тут, так сказать «up to you and your project». Главное чтобы решение было взвешенным и удовлетворяло обе стороны на текущем этапе проекта.

Но самое интересное впереди.

С пунктом 2 всё понятно — у Вас карт-бланш и если Вы провалили сроки, то делаем себе харакири down-level senior->professional и читаем мат часть.

А вот пункт 1 и есть Ваш Инь-Ян. Принимая его, Вы делите задачу на две части: первая будет реализована в этом спринте, вторая — когда-то потом. Так вот часто, очень часто, всегда о второй части забиваютзабывают.

«Я как бы за равенство полов, но только не в моём гареме», поэтому выработал следующую стратегию:

  1. При выборе «Quick Win» стратегии, задача разбивается на две (crt.fopen vs boost.iostreams)
  2. Для обех задач очерчивается объём работы (read settings vs preferences.subsystem) и производиться оценка (1m/h vs 4m/h)
  3. Первая часть заносится в текущий спринт вторая в back-log проекта
  4. Перед началом следующего спринта, анализируется возможность возврата долгов по некоторым пунктам и производиться переоценка по оставшимся долгам.

Каков выхлоп:

  1. Всегда перед глазами величина технического долга.
  2. Дисбаланс новые фичи\долг на спринте используется как параметр риск-менеджмента
  3. И крамольная фраза «Ну я же говорил ...» уже не просто сотрясание воздуха.

Можно говорить о техническом долге, как о тезисе, который достаточно широко распространён и выражет мнение о необходимости постоянного рефакторинга кода. Его отголоски можно найти и в ISO в пунктах, касающихся постоянного улучшения ISO 9001:2008 8.2. И как часть нашего мироощущения в разразе цена\качество.

Но есть проекты, цель которых возврат технического долга предыдущих разработчиков и в таких случаях двойная долговая вложенность и как следствие, часто «хочется нажраться в гов.. и сбацать пару старых хитов» :)

  • Популярное

29 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.
Еще нюанс. Обычно описанный Quick Win с возвратом к нему позже обходится много дороже чем простая сумма Quick Win + Long way.
Причем эта издержка растет со временем(хаки быстро забываются и никогда не документируются).

Мы обычно такие долги по какому то модулю аккумулируем до определенного предела(~5-8 тасков) и при следующем чейндж реквесте требуем время на редизайн модуля, и зачастую переписываем код модуля с нуля.(оптом дешевле)

Судя по колву комментов то, о чем эта статья не понял только я -)

да, умение писать понятно перенимать стоит не у этого автора. но суть в принципе прослеживается

+ 1, однако добавлю немного от себя.

1) С заказчиком нужно говорить на понятном ему языке: слова дизайн, рефакторинг, юниттесты и прочее напрочь выбросить из лексикона.
Надо общаться примерно так:
ПМ:- мы можем сделать быстро(дешево) и плохо, или медленно(дорого) и хорошо. Что ты выбираешь?
Заказчик: чем отличается «хорошо» от «плохо». Последнее будет делать то, что я хочу?
ПМ: что ты хочешь сейчас будет, но изменения и добавления будут стоить на порядок дороже. Тебе нужно что — то добавлять/изменять?
Заказчик: ээээ.....
ПМ: если мы будем постоянно работать в авральном режиме путаница будет нарастать и в конце концов проект придется выбросить на помойку потому, что в нем никто не разберется.
Заказчик: мммм
ПМ: если ты захочешь что — нибудь изменить в программе это будет стоить тебе в десять раз больше денег.
Заказчик: а если делать медленно и правильно
ПМ: это будет намного лучше. Гораздо быстрее работается, если у тебя порядок.

Заказчик: ну хрен с вами, делайте правильно.

Очень похоже :) Но по итогу, чаще всего, выбирают промежуточный вариант :) Чтобы и овцы сыты, и волки целы

Промежуточный вариант это получится и медленно и хреново

нет, это не совсем хреново и стоит не как самолет :)

<grammarnazimode>
Інь-Ян. І ніяких м’яких знаків.

</grammarnazimode>

Спасибо. Поправил.

Помещение технического долга в product backlog — очень правильное решение, потому что правильный product backlog и должен содержать в себе все виды работ по продукту, а не только «фичи».

Увы, это не решает проблему (де)приоритезации технического долга в случае недальновидного заказчика: «продукт работает, новые фичи пишутся — ну и фиг с ним, с этим каким-то техническим долгом, это все программисты придумали, чтобы денег не платить».

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

Мне сложно себе представить, как PO станет относится к таким задачам в беклоге. Как понять их приоритет? Как оценить их бизнес-ценность? Если он даже толком не понимает сути этой задачи?

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

Техническую суть задачи понимать PO не обязательно, с ним нужно разговаривать на языке «мы взяли кредит в N стори-поинтов, если мы его не отдадим в следующем спринте, через какое-то время разработка любой фичи в такой-то области системы будет гарантированно дороже на M стори-поинтов»

Думаю, что это такие ситуации все-таки нужно не «брать в долг», а «давать в долг» чисто политически. Дабы не искушать заказчика :) Лучше пусть он получит что-то от исполнителя с неким вау-эффектом и будет обязан :)

Если честно, не очень понял смысл комментария. Я имел в виду ситуацию, когда:

Заказчик: «нужна фича А».
Команда: «N человеко-часов». Нет, N мало, лучше M
Заказчик: «Да вы что, офигели?! Почему так долго и дорого?»
Команда: «Дизайн надо правильный сделать, рефакторинг, все дела»
Заказчик: «Я за это платить не буду!! Какое самое простое и быстрое решение?»
Команда: «Такое-то, но в будущем будет плохо потому-то и потому-то»

Заказчик: «Плевать, мне нужно дешево и сейчас»

Ну вот Вы и объяснили мой комментарий на собственном примере :) Вы продали заказчику «дешево и сейчас» с перекладыванием ответственности на него лично с обязательством заплатить денег потом за переделку «плохого» решения которое он «против вашей воли» перекосил в пользу сроков и стоимости с потерей качества.

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

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

Продали? Хм... Вот что произойдет практически в любой аутсорсинговой компании, если команда будет продолжать настаивать на дорогом и правильном решении: заказчик, не найдя общего языка с ПМом, заэскалирует вопрос account manager’у или, за неимением такового, высшему руководству. Последние же прийдут к ПМу и популярно объяснят ему, что нечего умничать и «играться в технологии», а надо удовлетворять заказчика здесь и сейчас.

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

Ну это произойдет и в продуктовой компании: если непрозрачно соответствие стоимости/сроков решения достигаемым бизнес целям — будут вопросы :)

Собственно, в топикстарте было предложено делать ТЭО. Правда, вариантов жизни бывает минимум 3, а не 2 :)

Вот что произойдет практически в любой аутсорсинговой компании, если команда будет продолжать настаивать на дорогом и правильном решении: заказчик, не найдя общего языка с ПМом, заэскалирует вопрос account manager’у или, за неимением такового, высшему руководству. Последние же прийдут к ПМу и популярно объяснят ему, что нечего умничать и «играться в технологии», а надо удовлетворять заказчика здесь и сейчас.

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

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

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

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

я понял :) по принципам эмпатического общения просто уточнил свою позицию как подтверждение вашей :)

Это клинический случай. Здесь ты хоть пиши в беклог долги, хоть не пиши — результат будет один и тот же, а расплачиваться клиент будет косвенно — увеличением времени на разработку новых фич и исправление дефектов (которых к тому же будет больше).

Если хочешь, чтобы кто-то для тебя что-то сделал — сделай это его проблемой. На клиентах проверено — работает. Вдобавок нужно учитывать, что клиенты часто понимают лишь два выражения проблемы: денежное и срочное (от слова сроки).

Пример: Если ты хочешь, чтобы мы сделали вот эту срочную фичу, то дедлайн сдвигается на N дней или нужно что-то выкинуть. Что, все остальное еще важнее? Тогда сдвигаем дедлайн. А, уже не надо ничего добавлять? Отлично!

С техническим долгом, понятно, сложнее. Его влияние для клиента заметно лишь косвенным образом. А команда не может внятно, на числах объяснить, что если мы зарефакторим вот этот кусок, то мы сэкономим в будущем N денег, и это N больше M, которое мы потратим на рефакторинг. Клиенты очень часто не технические люди, а люди бизнеса. Денежная или временная экономия для них — показатель.

Никогда не задумывался, что технический долг можно вот так вот трекать, так сказать «пАрами» задач. Мы все больше по-наколенному: ставим коменты «FIXME» в коде. Иногда с привязкой к номерам тикетов в трекере, но чаще без оных. Надо будет попробовать Ваш подход. Менеджменту ведь FIXME не продашь :-)

По-поводу отслеживания тех долга в большой команде — можно попробовать применить комбинированный подход. На макроуровне — тикеты, на микроуровне — FIXME комментарии в коде, полученные в результате код-ревью. Тикеты будут видны в трекере, а FIXME видны в среде разработки а также могут быть собраны в отчет на Continuous integration сервере (по-крайней мере Jenkins, он же Hudson имеет на борту плагин, который это делает).

FIXME можно заменить на TODO и продать менеджменту :)

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

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

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

ИМХО, Вы путаете понятия :) То, о чем Вы сказали — обычные баги в дизайне. Технический долг — результат осознанного смещения приоритетов после анализа и приоритезации.

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

Результат с точки зрения кода не всегда одинаков — баг ещё надо найти, а TODO места, как правило, отмечены красными флагами и пылающими кострами :)

ОК, различие принято :)


1. При выборе «Quick Win» стратегии, задача разбивается на две (crt.fopen vs boost.iostreams)
2. Для обех задач очерчивается объём работы (read settings vs preferences.subsystem) и производиться оценка (1m/h vs 4m/h)
3. Первая часть заносится в текущий спринт вторая в back-log проекта
4. Перед началом следующего спринта, анализируется возможность возврата долгов по некоторым пунктам и производиться переоценка по оставшимся долгам.

Если говорить ГОСТ-овским языком, то нормальное ТЭО решения с запасом на модернизацию и анализом необходимости этой модернизации по результатам эксплуатации. Молодец :)

Подписаться на комментарии