[Перевод] Как правильно чистить лук, или Почему разработка ПО выходит из-под контроля
Вы придумали стартап и с самыми лучшими намерениями нанимаете разработчика для реализации своей идеи. Но идет неделя за неделей, а приложение по-прежнему нуждается в доработке. Как-то незаметно появляются новые функции, и масштаб задачи понемногу расширяется.
Складывается ощущение, что проект зажил собственной жизнью и пытается сожрать вас.
Как так случилось? Может, наняли плохого разработчика? Кто-то ошибся в планировании проекта? А вдруг сама идея проекта была ужасной?
Возможно. Но часто проект бывает с самого начала обречен на провал из-за недопонимания одного важного момента.
Мы предполагаем, что продукт определяется набором функций, записанных на листочке бумаги: иногда что-то добавляется, иногда убирается —, но масштаб проекта всегда будто бы можно понять с одного взгляда.
Это предположение — неверно.
Проект — это не лист бумаги, не двумерный объект — у него есть глубина.
Каждую функцию на поверхности можно раскрыть — и так слой за слоем. Будь у меня склонность к громким заголовкам, я бы сказал, что всякое приложение — это лук, и нужно уметь правильно его чистить. Не очень понятно? Тогда давайте я поясню, что имеется в виду, и расскажу, почему не получается раскрывать слои приложения без слёз.
Переведено в Alconost
Наша библиотека — убийца всех библиотек
Рассмотрим конкретный пример. Подкиньте-ка мне идею.
Часто читателям нужна книга, которой нет в ближайшей библиотеке — зато она может быть у кого-то другого неподалеку. Сделаем же приложение, в котором одни люди будут отправлять заявки на книги, а те, у кого такие книги есть, будут отвечать. И с каждой операции будем брать процент.
Гениально.
Я знаю, мне уже об этом говорили. Итак, функционал довольно простой:
Можно отправлять ТЗ разработчику и начинать думать о том, как назвать наш стартап-убийцу: kaBooki? lib.rari.ly? reddit?
Что ж, поехали. Давайте взглянем поближе. (И кстати, «reddit» уже занят.)
Зададим пару вопросов о приложении и посмотрим, куда это нас приведет.
Как пользователи друг другу платят? Они просто передают друг другу наличные при встрече или оплачивают книги через приложение?
Они должны платить карточкой через приложение — так мы сможем снимать комиссию.
Каким образом запрашивается книга? В смысле, что конкретно пользователь делает в приложении? Заполняет открытую форму с названием книги и именем автора?
Хм… Пожалуй, пользователь ищет книгу в приложении и выбирает нужную.
Хорошо, значит, нам нужна база книг.
Ну да.
А что, собственно, представляет собой заявка на книгу? Может, продавцы видят список всех запрашиваемых книг? Или мы отправляем уведомления продавцам — как, например, Uber или Thumbtack?
Как Uber: мы отправляем заявки тем, у кого есть нужная книга.
Итак, продавцы должны занести в приложение все выставляемые на продажу книги?
Ага.
Как происходит передача книги? Пользователи отправляют их сами? Или мы занимаемся доставкой?
Доставка — наша забота.
Значит, понадобится система, которая будет говорить, какие книги и где нужно забрать, и куда их нужно доставить. Полагаю, водители захотят видеть самый короткий маршрут между этими двумя точками, верно?
Ладно, обойдемся без доставки. Пусть пользователи пересылают книги по почте.
Значит, мы будем показывать отправителю адрес получателя? Что мы будем делать с расходами на пересылку?
Вообще говоря, давайте лучше так: покупатель и продавец должны жить рядом. Тогда можно будет просто пойти и забрать книгу — и даже завести нового друга, здорово же?
Итак, нужно подбирать пользователей, которые находятся рядом. Как они будут находить друг друга? В приложении будет обновляющаяся в реальном времени карта, с помощью которой можно будет запланировать встречу?
Ладно, пусть так. Без разницы.
Цену устанавливаем мы — или пользователи договариваются сами?
Они сами будут договариваться о цене.
Как они будут это делать? В приложении будет встроенный чат?
Они могут просто позвонить друг другу.
Понятно. Так нам нужно подтверждать номера по SMS? А как насчет… впрочем, думаю, вы уже поняли. Я могу продолжать бесконечно.
Не надо, прошу.
Давайте посмотрим, как выглядит список функций теперь:
И каждый пункт можно раскрыть еще по нескольку раз. А мы ведь просто сняли первый слой нашей луковицы — и вот что получилось.
Тише, тише, не надо плакать.
Так что же произошло?
В первую очередь давайте проясним, что не является причиной такого расширения функционала.
Нагромождение ненужного функционала? Нет.
Это случай, когда в продукт добавляются новые возможности. Если посмотреть на окончательный список функций, то мы увидим, что каждый пункт нужен для работы исходной идеи.
Вопросы технической реализации? Тоже нет.
Мы же не выбирали подходящую архитектуру для системы чата и не искали платежную платформу, которую будет проще всего внедрить.
Речь не об этом. Хороший разработчик расскажет о самых разных вариантах технической реализации —, но он не сможет решить, какие функции вам нужны.
Маркетинговые соображения? Мимо.
Мы не задаемся вопросом, нужен ли будет кому-то такой продукт, не спрашиваем, что заставит первых пользователей платить за подписку, когда других пользователей совсем мало, и не думаем, будут ли пользователи вообще готовы платить за такой сервис.
Эти вопросы связаны с проверкой идеи, определением рыночной ниши продукта и стратегией ценообразования. И это, конечно, важные вопросы. Но и они — не причина разрастания списка функций.
Ага, а еще глобальное потепление и Баба-яга тут тоже ни при чем. Может, назовете причину проблем с этим вашим «луком» или мы будем по одному перебирать все, что причиной не является?
Ай, с вами скучно. Ладно. Поясняю, что произошло.
Мы совершенно неверно представили себе, как обстоят дела со сложностью ПО.
Мы рассчитывали, что сложность отдельной функции представлена ее описанием. Ну правда же: чтобы написать код или что там еще делают программисты, может, и нужно время, но конкретную функцию все-таки можно описать парой слов. «Пользователь делает X с помощью Y». Так?
Нет.
Функционал ПО напоминает скорее фракталы
Чем ближе смотреть, тем больше деталей появляется.
А разве луковица — фрактал?
Не-а, у нас теперь другая метафора.
Мы начали с общего представления о том, какая функциональность нужна. Но разработка приложения и пользование им — это взгляд с намного меньшего расстояния. Мы исследуем приложение шаг за шагом, и на каждом шагу могут возникать новые задачи. Чтобы их решить, может понадобиться переработать конкретный шаг, добавить новые шаги и даже совершенно новые функции.
Представьте, что вы планируете маршрут от дома до работы. На карте маршрут может выглядеть как прямая линия.
Но если увеличить карту, окажется, что прямая линия не вписывается в сетку городских улиц: на маршруте появятся остановки общественного транспорта, подъемы и спуски, различные препятствия. Если идти на работу пешком, маршрут будет один, если ехать на велосипеде — другой, на машине — третий.
Создание ПО во многом похоже: чем пристальнее смотреть, тем больше открывается необходимых для решения задачи деталей.
Отлично. Распишите все полностью до самых мелких деталей. Именно это мне и нужно было. Но… так, наверное, мой продукт никогда не выйдет в свет?
Коротко говоря, и да, и нет. Сложность увеличивается потому, что мы начинаем с описания функции, которая обычно представляет собой цель проекта, а затем опускаемся на уровень ниже и пытаемся реализовать каждый шаг, необходимый для достижения этой цели. Чем больше мы углубляемся, тем сложнее становится представление о функции.
Впрочем, сложность сама по себе — не проблема. Проблема появляется, когда мы решаем, каким образом эта сложность будет раскрываться. Мы передаем описание функционала разработчику. Через несколько недель у нас есть первая версия приложения, и мы ее проверяем: проходимся по приложению шаг за шагом и замечаем огромные дыры в функционале. Мы записываем замечания, отправляем их разработчику и ждем версии номер два.
В конце концов, повторив все это несколько раз, мы получаем довольно неплохое решение. Беда только в том, что такая разработка получается очень уж долгой: каждый цикл занимает недели и даже месяцы.
Раскрывать сложность решаемой приложением задачи придется в любом случае.
Но играть в «горячую картошку» с разработчиком, многократно передавая приложение с доработки на проверку функционала и таким образом раскрывая его сложность, — это дорого и долго.
А делать нужно так:
Нам нужно как можно глубже раскрыть сложность до того, как начнет писаться код. Снимая слой за слоем, мы должны составить как можно более продуманный и исчерпывающий список функций — и хотелось бы сделать это быстро и недорого.
Решение — гонять по циклу доработки не приложение, а техническое задание.
Мы должны перейти от такой модели:
К вот такой:
Чтобы работа была эффективной, нам понадобится, во-первых, составить каким-то образом список функций, чтобы с ним можно было работать. А во вторых — придумать, каким образом этот список функций можно эффективно исследовать.
Вот об этом мы сейчас и поговорим.
Схема функционирования
Нам придется перестать думать о приложении с точки зрения бизнеса и начать думать как пользователь — именно на этом уровне мы сможем разобраться со сложностью ПО.
Для начала составьте список целей пользователя: для чего пользователи будут заходить в приложение?
Затем спланируйте последовательность действий пользователя, шаг за шагом проходя и записывая все этапы, необходимые для достижения цели.
Так вы составите схему, по которой пользователи будут действовать в приложении.
Делается это самыми разными способами. Можно просто схематично изображать каждый шаг. Можно рисовать макеты экранов, по которым перемещается пользователь. Можно нарисовать блок-схему — на бумаге или в каком-нибудь приложении.
Пример простого макета (источник)
Какой бы вариант вы ни выбрали, постарайтесь, чтобы он не замедлял работу: если вы не владеете графическим редактором на «отлично», лучше возьмите в руки карандаш и бумагу.
На схеме должен быть представлен каждый экран приложения. Например, если на каком-то шаге — несколько экранов, разбейте этот шаг: нам ведь нужно как можно больше подробностей.
По мере того как вы будете проделывать описанное выше, сложность приложения будет частично раскрываться. Но мы пойдем еще дальше.
Спрашивайте обо всем
Задавать вопросы, как мы делали это чуть раньше, можно почти бесконечно. Правда, бывает сложно сообразить, с чего начинать.
Но не отчаивайтесь: я составил список общих вопросов, применимых к большинству ПО. Они входят в четыре больших категории, на которые можно ориентироваться, разрабатывая собственную схему.
Внимательно просмотрите все этапы на своей схеме и по каждому из них задайте перечисленные в списке вопросы. Если при ответе на вопрос будут выявлены новые шаги — добавьте их на схему.
Далее — список вопросов.
Вводимые пользователем данные
Эти вопросы относятся к информации, которую пользователь передает в продукт.
- Какие данные вводит пользователь?
- Ввод данных свободный или интерактивный?
- Примеры свободного ввода: выбор изображения для загрузки, запись видео, свободный ввод текста.
- Примеры интерактивного ввода: ввод текста в поле поиска, отображающее результаты, из которых можно выбирать, выбор адреса на карте, выбор из заранее определенного набора вариантов.
- Могут ли вводимые данные быть неверными? Что приложение должно в этом случае делать?
- Используется ли пассивное получение данных? Самый распространенный пример — местоположение пользователя по GPS.
Какие сведения нужны продукту от нового пользователя? Сможет ли пользователь изменить их позже?
Информация, показываемая пользователю
Если выше мы говорили о вводе данных, то теперь рассмотрим вывод.
- Какие данные показываются пользователю на конкретном экране?
- Как они отображаются? Примеры: текст, изображения, карты, списки, диаграммы.
- Нужно ли каким-либо образом упорядочивать данные? Примеры: по новизне, расстоянию от пользователя, релевантности.
- Использует ли приложение активную передачу исходящих данных? Примеры: электронные письма, push-уведомления, SMS-сообщения.
Взаимодействие между компонентами
Эти вопросы касаются того, как разные компоненты проекта (пользователи, продукт, другие сервисы) взаимодействуют между собой.
- Взаимодействуют ли пользователи друг с другом? Примеры: обмениваются сообщениями, добавляются в друзья, «лайкают» или помечают тегами материалы других пользователей.
- Взаимодействуют ли пользователи с внешними сервисами? Примеры: платежные службы, отслеживание посылок, вход через соц. сети.
- Взаимодействует ли продукт с внешними сервисами? Примеры: сервисы поиска местоположения, API прогноза погоды, социальные сети («К нам присоединился ваш друг Х! Загляните к нему на страницу!»).
Функционал для владельца бизнеса
Вопросы о том, что вам как владельцу бизнеса нужно от продукта.
- Нужно ли вам получать оповещения или сводки по электронной почте либо посредством иного средства передачи?
- Нужна ли отдельная система для вас или ваших сотрудников? Примеры: водительское приложение для службы доставки, интерфейс управления заказами в реальном времени для кухонного персонала.
- Нужен ли интерфейс для ручного утверждения пользователей или их материалов?
- Нужна ли система модерации материалов? С ее помощью администраторы смогут легко удалять публикации пользователей, отключать их учетные записи и т. д.
Как-то… многовато вопросов.
Именно! Причем это — самые общие вопросы, о которых часто забывают в начале работы над проектом. Для каждого отдельного продукта по мере работы над ним обязательно появится множество других более конкретных вопросов.
Собираем всё вместе
Построение схемы, вопросы и ответы на них помогут понять, что вы упускаете из виду. Повторите всё это несколько раз — и у вас должен появиться внушительный список функций, в отношении которых вы будете чувствовать себя гораздо увереннее.
Я-то надеялся, что у вас есть какой-нибудь хитрый прием, который поможет вытащить мой проект. А над этим вот всем, похоже, придется хорошенько поработать.
Конечно. Но на каком-то этапе «это вот всё» так или иначе придется делать.
Не забывайте, почему мы вообще за это взялись: функции ПО кроют в себе неочевидную сложность, которую в любом случае придется выявить — вы же можете лишь выбрать, когда приниматься за чистку этой «луковицы».
По сути, есть два варианта:
- Можно прояснить цели пользователей, построить макет или блок-схему, задать множество вопросов касательно своих же предположений и «раздеть» нашу луковицу, как мы сделали это чуть выше. Но есть, конечно, и другой вариант.
- Можно сразу поставить перед разработчиком задачу сделать приложение, а затем с каждой новой версией постепенно раскрывать все эти нюансы — по одной неделе на каждый «слой». Так вы за несколько месяцев узнаете всё то же, что можно было бы понять за неделю работы с карандашом и бумагой.
Теперь вы понимаете, почему проекты по разработке ПО иногда превращаются в чудовищ, которые пытаются сожрать своего хозяина живьем.
Так что вперед — исследуйте функционал своего проекта: стройте схемы, озвучивайте свои предположения и задавайте по ним вопросы. Так вы сможете быстро и без особых затрат раскрыть основную часть предстоящих задач.
Избавьте себя от лишних волнений и мук, выпустите свой проект в мир — и пусть он расцветет.
Alconost is hiring
Перевод статьи выполнен в Alconost.
Нам в Alconost в минский офис для работы над проектом Nitro (профессиональная служба живого онлайн-перевода) нужен крутой Frontend-разработчик (React.js). Присылайте рассказ о себе и примеры того, что делали раньше на dev@alconost.com
Alconost занимается локализацией игр, приложений и сайтов на 68 языков. Переводчики-носители языка, лингвистическое тестирование, облачная платформа с API, непрерывная локализация, менеджеры проектов 24/7, любые форматы строковых ресурсов.
Мы также делаем рекламные и обучающие видеоролики — для сайтов, продающие, имиджевые, рекламные, обучающие, тизеры, эксплейнеры, трейлеры для Google Play и App Store.
Подробнее: https://alconost.com