Як навчитися оцінювати завдання, якщо не вмієш: 4 фактора складності

Коли я був початківцем програмістом, – а втім, і пізніше, коли я був початківцем провідним розробником, – я думав, що спрогнозувати терміни, в які ти щось зробиш, абсолютно неможливо. Або ж, що хороший прогноз вимагає дуже детальних проектування і підготовки, приблизно таких же по тривалості, як і сама задача.

Пізніше, звичайно, я виявив, що по темі прогнозів написано кілька розумних книжок, які в сумі з деяким досвідом роблять оцінку завдань хоч і невдячною, але і небезнадежным заняттям. Самим зручним способом, звичайно, є оцінка по аналогії: коли ти вже робив щось подібне, ти досить точно знаєш, яких зусиль це завдання вимагатиме. Але як бути в ситуації, коли досвіду порівняно небагато або аналогії брати нізвідки, а оцінити все ж хочеться?

В одній з команд, де я працював, ми придумали оригінальний метод для попередньої оцінки завдань. Метод синтезує деякі відомі з літератури прийоми, але в цій формі, мабуть, ніким не описаний. Концепція була наступною: об'єктивність (зв'язок з вимірними показниками); інтегрованість з Agile; повторюваність; швидкість оцінки (менше 0.5% від обсягу завдання); доступність для початківців розробників. Я буду радий обговорити нашу ідею і не виключаю, що комусь із Хабрааудитории вона припаде до душі.

Чотири фактори складності: аналіз завдання
Отже, беремо завдання (погано поставлене, формально не описану — все як в житті). Виконуємо експрес-аналіз: а саме, збираємо в голові (чи на дошці) інтуїтивне уявлення про те, яку функціональність потрібно реалізувати і як технічно це завдання може бути виконана.

Нашою першою метою є конкретизувати виникло уявлення настільки, щоб можна було його чисельно оцінити за нижче наведеними 4 шкалами.

Фактори складності, проекції, умовно називаються так:

  • «Поверхню»
  • «Тестування»
  • «Вимоги»
  • «Технічний ризик»
Ці терміни в методі розуміються досить оригінально (наприклад, «поверхня» — це взагалі нестандартне поняття), але сформульовані так, щоб мати зв'язок з об'єктивною реальністю, тобто з вимірними величинами:

Поверхня у загальному випадку — це площа зіткнення нашої доопрацювання з зовнішнім світом. Наприклад, для GUI компоненти слід скласти якесь кількісне уявлення про майбутнє числі елементів інтерфейсу. Для бібліотеки — про числі методів в публічному API. Для баг-фікса — про обсяг порушеного коду. Для стейт-машини — про класах входять подій. У випадку, якщо у нас в задачі «і те, і інше, і третє», то треба задуматися, що з цього зовнішнє, а що, по суті, приватне, і саме публічну частину і оцінювати.

Тестування — це наше уявлення про кількість елементарних автоматичних тестів, які нам доведеться написати для виконання в стилі TDD. Це не обов'язково означає, що ми будемо розробляти через тестування (кажуть, справжні ковбої взагалі тестів не пишуть), але для оцінки складності задачі нам потрібно задуматися, який обсяг тестів їй відповідає.

Вимоги — це наше уявлення про обсяг того, що в класичних підходах називається вимоги (requirements). Ми можемо розуміти цей фактор як розмір специфікації, яку нам довелося б написати, якщо б ми хотіли повністю формально поставити завдання. Природно, ми практично ніколи не витрачали час на складання таких специфікацій — складання вимог в наш процес не входило — але мали уявлення про те, наскільки об'ємними подібні документи виходять. Виносимо оцінку у формі: «Щоб формально це описати, треба було б сторінок 15» і йдемо далі.

Технічний ризик — цей фактор відображає очікування того, що доведеться робити якесь дослідження, пробувати кілька підходів, або викидати частину роботи з-за того, що у нас щось не зростеться. В теорії, цю величину можна виразити числом від 0% до 100%, але на практиці це найбільш суб'єктивна з 4 величин. Можна діяти так: для оцінки ризику, придумуємо всі способи, як можна цю задачу завалити. Якщо в результаті ми відчуваємо депресію і у нас з'явилися серйозні сумніви, що в результаті ми впораємося в розумні строки — то ставимо оцінку, близьку до максимальної.

Отримані 4 «проекції» утворюють свого роду профіль завдання — стає зрозумілим, що становить її основну складність. Одночасно при аналізі задачі відбувається валідація (перевірка) її постановки: якщо ви, приміром, усвідомлюєте, що вам невідомо, як ви будете тестувати свою доопрацювання, то швидше за все приступати до написання коду не можна. Певне значення має і співвідношення проекцій — великі показники відразу по декільком факторам натякають на те, що в задачі є «прихований обсяг» (що загрожує багаторазовим перевищенням наших очікувань), в той час як «плоскі» завдання (завдання з однією домінуючою «проекцією») зазвичай легко проглядаються і робляться в очікуваний термін. У тому ж випадку, коли завдання спочатку здавалася невеликий, і справді виявилася невеликий за всіма оцінками, час на роздуми все одно було витрачено не дарма: як мінімум, ми підтвердили, що у нас є достатня розуміння того, що треба реалізувати.

Такий експрес-аналіз проводиться швидко, і дає досить чітке уявлення про складність і трудомісткість завдання. Можна було б і закінчити на цьому, обмежившись якісним підходом. Однак, ми насправді пішли набагато далі і синтезували з цієї концепції експериментальну метрику.

Нижче буде викладено спосіб отримати з 4 якісних оцінок кількісну величину, яка, в кінцевому рахунку, допомагає скласти бэклог ітерації або позначити прогноз часу. За нею не стоїть серйозного наукового дослідження, але в нашій практиці він давав досить непогану точність при мінімальних витратах сил.

Експериментальна метрика
Як ми вже зрозуміли, на початковому етапі 4 проекції виражаються приблизно так: «у нашому компоненті очікується штук п'ятдесят методів, двісті тестів; потрібно було б 20 сторінок опису, якого ніколи не буде, і є приблизно 10% шансів все переробляти заново». Тепер, коли ми всі оцінили, нам потрібно ці кількості агрегувати. Але просто так скласти тести і шанси, звичайно ж, не можна, тому наші оцінки потрібно конвертувати в умовні одиниці складності.

Складність, взагалі, розуміється як міра тимчасових витрат за вирахуванням написання очевидного бойлерплейта і всіх інших рутинних і передбачуваних операцій. Для початкової конвертації, використовується наступна нелінійна шкала:

  • 0 — означає «все просто» (можна відразу подати у всіх деталях, що потрібно зробити, і власне зробити за незначний термін);
  • 1 — це та складність, яку можна подолати за квант часу (скажімо, за 4 або 8 годин)
  • 3 — більше одиниці в 3-5 разів, що вже вважається досить високим, дещо проблемним значенням
  • 5 — максимальна оцінка, означає «епік» (так складно, що точно варто розбити, урізати або відмовитися)
Формула
Для одержання підсумкової метрики підсумовуємо всі наші оцінки складності в одиницях за чотирма шкалами.

Однак, якщо у двох і більше шкалах у нас вийшло ≥2 два найбільших числа ми не складаємо, а перемножуємо.

Ілюстрація:

Завдання 1. 1 0 0 0 -> 1 -> 1
Завдання 2. 1 0 2 0 -> 1+2 -> 3
Завдання 3. 1 1 2 0 -> 1+1+2 -> 4
Завдання 4. 3 3 1 2 -> 3*3+1+2 -> 12
Завдання 5. 1 4 1 5 -> 4*5+1+1 -> 22
Використання
Метрика складності дає уявлення про обсяг інтелектуальної роботи, явному і прихованому, і навіть може бути конвертована, майже механічно, в песимістичну оцінку часу. Як це зробити, дивіться нижче, але спочатку я розгляну кілька більш легких сценаріїв використання. Деякі з нижченаведених способів взагалі не прив'язані до того, як саме ви отримали метрику — вони просто показують, як можна отримати якусь користь з такої числової величини.

Вибір технічного рішення
Коли ви пишете великий і складний проект, буває, що у вас є два-три прийнятних способу додати якусь функціональність, і вам потрібно заздалегідь передбачити, який шлях буде простіше. Щоб прийняти рішення, ви можете оцінити кожен з варіантів по 4 факторам і порівняти значення (правда, вибираючи більш простий шлях, варто задуматися, чи не додаєте ви технічний борг).

Валідація завдань
Метод володіє цікавою здатністю виявляти приховану складність завдання за рахунок того, що в ньому влаштована арифметика і шкали (той самий прихований обсяг; див. також розділ «досвід використання»). Якщо ви не обмежуєтеся якісним аналізом, а вираховуєте метрику, то ви можете зробити постановку завдань краще. Для цього, вводяться два критерії:

  • Метрика складності не повинна перевищувати деякої межі. Завдання за обсягом відносно однорідні (не надто маленькі, не дуже великі);
  • Немає «тривимірних» і «чотиривимірних» завдання, тобто завдання отримує високі оцінки максимум по 2 проекціями.
У цих критеріях вводяться деякі константи, що характеризують бажаний розмір розбиття. Їх можна настроювати. Я віддаю перевагу варіант «не більше 10 по метриці, не більше 1 в молодших 2 проекціях», але це виходить досить крупно.

Складання бэклога
Методологій розробки ПЗ існує безліч, але значна частина їх передбачає певну ітеративності, яка полягає в тому, що команда ставить собі за мету на період часу і визначає набір завдань, які для досягнення цієї мети треба зробити. В кінці ітерації повинна вийти готова до постачання версія продукту.

На початку ітерації проводиться оцінка того, що взагалі можливо зробити за цей період часу і відбувається уточнення завдань, в результаті чого виходить якийсь перелік, аналогічний бэклогу з User Story та/або інших форм опису завдань.

Відоме перевагу стандартного бэклога у форматі User Story перед «планом робіт на період» полягає в тому, що його не обов'язково точно оцінювати, в силу своебразной «магії» скрама. Але тут є важливий нюанс. Якщо завдання, як це відбувається у багатьох командах, розбиті не в канонічному форматі User Story, а більш крупно, або більш «архітектурно», то згадана «магія» легко ламається: якість оцінки розміру задачі на початку ітерації починає відігравати критичну роль. Це дуже поширена ситуація, в якій вам може знадобитися і набір історичних даних по минулим завданням, і вычислимая метрика, яку ви використовуєте на початку ітерації як оцінку розміру для завдань, що викликають сумніви. Оскільки неправильно вибраний склад ітерації завдає шкоди і продукту, і мотивації розробника, докладати зусилля до адекватної оцінки завдань буває більш ніж виправдане. Я б рекомендував це робити.

Boost your Scrum
Scrum-команди, як правило, виставляють оцінку завданням в умовних одиницях (Story Point). Зробити це не завжди просто. Практикуються щодо складні процедури, такі як Planning Poker.

Застосування методу в стилі Agile полягає в тому, що ми вважаємо запропоновану метрику в тих випадках, коли у нас є сумніви щодо розміру задачі або можливості її реалізації. Оскільки для окремої задачі всі розрахунки і оцінки за цим методом можна зробити в розумі, це проходить досить безболісно і без великих методологічних суперечок. Є також можливість «партизанського» застосування цього методу — якщо завдання оцінюєте ви один, як розробник, і 4-х факторний метод у вас працює, то вам необов'язково розповідати на стендап всю цю механіку.
 
Потрібен план?
Заздалегідь прошу вибачення у тих читачів, для яких «планування» — це лайливе слово. Решту читачів хочу порадувати, що з метрик виводяться і безпосередні тимчасові оцінки, якщо діяти акуратно. Стратегічно планувати так, напевно, не вийде. Однак, одним з переваг методу є можливість попередньо оцінювати досить великі блоки завдань.

Планування з метриками будується на припущенні, що завдання щодо свого майбутнього фактичним обсягом будуть співвідноситися як їх метрика обсягу. Звичайно, складність і обсяг поняття не еквівалентні, адже часом лише частина зусиль розробника спрямована на власне рішення задачі. Якщо вам, крім програмування, доводиться займатися якоюсь малоинтеллектуальной діяльністю, зразок написання тонн XML, ручного неефективного тестування або трудомісткої процедури деплоя; якщо ви до того ж ведете переговори з замовником і пишете манускрипти документації, і всі такі заняття нерівномірно розподілені між завданнями — я вам можу лише поспівчувати. Вам доведеться самим придумати, як оцінити непрограммистскую і малоинтеллектуальную діяльність. Однак якщо такої роботи трохи, – а в хороших проектах її небагато, – цілком можна собі дозволити вважати для цілей планування, що Обсяг == Складність, і не вносити додаткові поправки.

Коли мені доводилося складати середньострокові плани, я надходив наступним чином:

  1. Виділяється певний перелік завдань і обчислюється наша метрика по кожному пункту.
  2. Завдання, оцінки яких сигналізують про необхідність зміни або розбиття, розбиваються (критерії — див. «Валідація завдань»)
  3. Далі ми, орієнтуючись на свої інтуїтивні відчуття, стискаємо або розтягуємо цей графік за часом, більш-менш дотримуючись обчислені пропорції обсягу та не допускаючи виникнення нереалістично виглядають пунктів.
Звичайно, це досить наївний підхід, – так можна складати план і без всякої оцінки завдань, – але результат буде гірше. Метрика допомагає тим, що в момент планування ми бачимо чисельні оцінки (співвідношення між завданнями), що страхує нас від спотворень і не дає скоротити терміни нижче межі розумного. Виходить, що кінцевому рахунку, термін все одно вибирається не механічно, а почасти інтуїтивно, але при серйозній підтримці з боку метрики.

Альтернативно, якщо ви плануєте для себе одного, можна зробити простіше: обчислити історично деякий коефіцієнт «швидкості» і механічно обчислювати прогноз часу, ділячи на коефіцієнт метрику черговий завдання. Але так планувати виходить гірше, ніж коли ви бачите цілісну картину. До того ж, калібрування такого коефіцієнта — заняття не з приємних. Схожий підхід зі «швидкістю» цілком працює в Scrum з його BurnDown діаграмами, але там він виглядає більш ефективним і природним. Можна сказати, що концепція Scrum Velocity являє собою більш тонко влаштований механізм, ніж просто пропорція між обсягом і часом.

Досвід використання
Для невеликої завдання, як показує практика, оцінки і арифметика виконуються в межах хвилини в розумі. Для великих компонент потрібно трохи більше часу, але все одно метод може виглядати як швидкий, усний розрахунок, що дає прийнятний по точності результат — зазвичай, більш точний, ніж інтуїтивно озвучений прогноз у N днів. Бували випадки, коли я ці цифри підраховував і складав у думці на мітингу, поки мої колеги з інших команд займалися справжньою роботою — потайки зафарбовували клітинки в Buzzword Bingo.

Чи можна назвати цей метод дуже простим, але зате він відрізняється корисної здатністю виявляти неявную складність — навіть таку, яка ховається в поганих бібліотеках та інструментах, поганий архітектурі, в нелінійності роботи, в технічному борг. Почасти цьому сприяє нелінійна арифметика, але в цілому виявлення прихованої складності відбувається швидше за рахунок того, що шкали оцінки не цілком ортогональны: розгляньте кілька варіацій реальної задачі, і ви помітите, що навіть зміни, що дають приріст переважно за однією шкалою, все одно почасти проявляються і в інших. При цьому характерно, що в одних випадках таке перенесення проявляється сильно, а в інших — слабко. І чим менше виражений перенесення, тим інтуїтивно простіше і легше виглядає відповідна доопрацювання завдання, чи не так? Формула, дійсно, використовує те спостереження, що всілякі «підводні камені» ніколи не проявляються переважно за окремою шкалою, але їх наявність суттєво піднімає вгору одночасно дві-три проекції. Нелінійність формули «ловить» цей ефект, створюючи істотну надбавку до розраховується значення.

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

Сам я практикую цей метод епізодично вже кілька років. Моя прихильність до нього викликана кількома причинами. По-перше, при обережному застосуванні він дає помітно більш точний прогноз, ніж інші примітивні методи. По-друге, він досить гнучко адаптується до тих чи інших методологій розробки: з деякою натяжкою його можливо застосовувати і в «чистому» Agile оточенні, і в гібридних проектах, і в умовно «класичному» проектному менеджменті з Microsoft Project поверх команди програмістів. Я також помічав у ньому якусь приємну масштабованість — іноді можливо застосовувати подібну оцінку не тільки в малих (bug, story...), але і в більш великих часових масштабах (блок функціональності, компонент). Нарешті, метод допомагає навчанню оцінює: завжди є можливість порівняти фактично відбулися показники (обсяг коду, складність тестування і т. д.) зі своїми ранніми оцінками, і зробити суттєві висновки.
 
∗ ∗ ∗
У своїй статті я в принципі не ставив метою обговорювати, чи потрібно взагалі оцінювати завдання в проектах, і потрібно застосовувати якісь метрики при розробці ПО, а просто хотів запропонувати корисний інструмент для тих, у кого така потреба існує. Мене підкуповує те, що при досить високих показниках цей метод маловідомий; і зізнатися, мені було б дуже цікаво знайти початковий джерело деяких з його концепцій.

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


Буду радий вашій критиці і коментарям.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.