Есть спор, который я слышу почти на каждом проекте, только в разных костюмах. Клиент говорит: «Давайте сделаем систему гибкой, чтобы потом можно было настроить что угодно». Программист говорит: «Давайте сделаем универсальное решение, вдруг пригодится». И все кивают, потому что гибкость звучит как безусловное благо. Кто же будет против того, чтобы система умела больше?
Я буду против. Не всегда, но очень часто. Потому что гибкость не бесплатна. Каждое «универсальное» решение добавляет уровень абстракции, который усложняет жизнь разработчикам, пользователям и в итоге бюджету. Мы слишком часто приносим простоту в жертву воображаемой гибкости «на будущее», которое так и не наступает.
Швейцарский нож на сто лезвий
Представьте швейцарский нож, в котором сто лезвий: пилы, отвёртки, открывалки, лупа, зубочистка, штопор, ножницы и ещё восемьдесят насадок неизвестного назначения. Он тяжёлый, его неудобно держать, и чтобы найти нужное лезвие, приходится раскрыть половину. А когда нужно забить гвоздь, оказывается, что молоток всё-таки лучше. Простой, тяжёлый, с одной функцией. Зато этой функцией он владеет в совершенстве.
Программные системы, которые пытаются уметь всё, похожи на этот нож. Конструктор форм, в котором можно собрать любую форму, но собрать простую анкету занимает час. CRM, которую можно настроить под любой бизнес, но для этого нужен отдельный специалист на полгода. Система правил, где бизнес-логику можно задавать в интерфейсе, а потом никто не может понять, почему заказ ушёл не тому менеджеру.
Отсюда и простое наблюдение: универсальные системы часто проигрывают узкоспециализированным. Не потому что они плохо сделаны, а потому что за каждую возможность «настроить что угодно» платит каждый пользователь каждый день, даже если ему эта возможность не нужна.
Цена гибкости
В чём конкретно выражается цена? Во-первых, в разработке. Гибкое решение всегда сложнее простого. Вместо того чтобы написать «если заказ больше суммы X, дать скидку», нужно построить механизм правил, интерфейс для их настройки, хранение, проверку, обработку конфликтов между правилами. Работа увеличивается в разы.
Во-вторых, в поддержке. Чем больше вариантов поведения у системы, тем больше комбинаций нужно тестировать, тем больше мест, где может спрятаться ошибка. Одна настройка в сочетании с другой даёт результат, о котором никто не подумал.
В-третьих, в понимании. Простую систему может понять новый сотрудник за день. Гибкую систему, настроенную пять разных раз пятью разными администраторами, не может до конца понять никто. И когда что-то ломается, начинается археология.
Поэтому я называю избыточную гибкость техническим долгом, который Вы берёте под огромные проценты прямо сейчас. Обычный технический долг откладывает работу на потом. Избыточная гибкость, наоборот, заставляет платить сразу, за возможности, которые могут никогда не понадобиться.
Принцип: гибкость там, где меняется
Значит ли это, что гибкость не нужна вовсе? Конечно, нет. Вопрос в том, где именно она нужна. Правило, которому я следую: не делайте систему гибче, чем того требует текущий бизнес-план. Гибкость нужна там, где изменения действительно происходят часто, и где Вы уже видели эти изменения, а не придумали их.
Например, если цены у компании меняются каждую неделю, а маркетинг постоянно запускает новые акции, механизм настройки скидок окупится. Если же структура заказа не менялась пять лет, не нужно делать её настраиваемой «на всякий случай». Если когда-нибудь понадобится, переделаете. Это будет дешевле, чем годами поддерживать гибкость, которой никто не пользуется.
У программистов для этого есть хорошее правило с забавным названием YAGNI: «тебе это не понадобится». Не делай того, что, возможно, пригодится в будущем. Делай то, что нужно сейчас, но так, чтобы это было легко изменить. Последняя часть важна: простота не означает небрежность. Простой, чистый, понятный код как раз легче всего менять, когда придёт настоящая потребность.
Чем жертвовать
Любая система это компромисс. Нельзя одновременно получить максимальную гибкость, максимальную простоту, максимальную скорость и минимальную цену. Чем-то придётся пожертвовать, и важно сделать этот выбор сознательно, а не позволить ему случиться самому.
Мой обычный совет клиентам: жертвуйте гибкостью в тех местах, где бизнес стабилен, и держите её там, где бизнес живой. Жертвуйте универсальностью ради того, чтобы основной сценарий работал идеально. Пусть система делает одну главную вещь очень хорошо, а не сто вещей посредственно. Если позже понадобится сто первая вещь, добавьте её тогда, когда станет понятно, какой именно она должна быть.
Как мы это решаем
В Ingello мы нашли для себя интересный выход из этого спора. Вместо того чтобы делать одну гибкую систему на все случаи, мы делаем гибким процесс создания систем. Fractal генерирует под каждого клиента простую систему, заточенную под его процессы, из формального описания. Если процессы меняются, меняется описание, и система перегенерируется. Пользователь получает молоток, а не швейцарский нож. А гибкость живёт на уровне генератора, где за неё платим мы один раз, а не клиент каждый день.
Если Вы сейчас выбираете или заказываете систему, задайте один вопрос про каждую «гибкую» функцию: что именно мы собираемся менять и как часто это происходило за последний год? Если ответ «пока ничего, но вдруг», это кандидат на жертву. Вашим пользователям будет проще, а бюджету легче.