Гнучкість проти простоти. Чому потрібно чимось жертвувати.

Вічна суперечка: гнучкість проти простоти. Чому універсальні системи часто програють вузькоспеціалізованим.

Гнучкість проти простоти. Чому потрібно чимось жертвувати.
INGELLO / BUSINESS2233

Є суперечка, яку я чую майже на кожному проєкті, тільки в різних костюмах. Клієнт каже: «Зробімо систему гнучкою, щоб потім можна було налаштувати що завгодно». Програміст каже: «Зробімо універсальне рішення, раптом знадобиться». І всі кивають, бо гнучкість звучить як беззаперечне благо. Хто ж буде проти того, щоб система вміла більше?

Я буду проти. Не завжди, але дуже часто. Бо гнучкість не безкоштовна. Кожне «універсальне» рішення додає рівень абстракції, який ускладнює життя розробникам, користувачам і зрештою бюджету. Ми надто часто приносимо простоту в жертву уявній гнучкості «на майбутнє», яке так і не настає.

Швейцарський ніж на сто лез

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

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

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

Ціна гнучкості

У чому конкретно виражається ціна? По-перше, у розробці. Гнучке рішення завжди складніше за просте. Замість того щоб написати «якщо замовлення більше за суму X, дати знижку», треба побудувати механізм правил, інтерфейс для їх налаштування, зберігання, перевірку, обробку конфліктів між правилами. Роботи стає в рази більше.

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

По-третє, у розумінні. Просту систему новий співробітник може зрозуміти за день. Гнучку систему, налаштовану пʼять різних разів пʼятьма різними адміністраторами, до кінця не може зрозуміти ніхто. І коли щось ламається, починається археологія.

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

Принцип: гнучкість там, де змінюється

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

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

У програмістів для цього є добре правило з кумедною назвою YAGNI: «тобі це не знадобиться». Не роби того, що, можливо, знадобиться в майбутньому. Роби те, що потрібно зараз, але так, щоб це було легко змінити. Остання частина важлива: простота не означає недбалість. Простий, чистий, зрозумілий код якраз найлегше змінювати, коли прийде справжня потреба.

Чим жертвувати

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

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

Як ми це розвʼязуємо

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

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