Вы придумали стартап и с самыми лучшими намерениями нанимаете разработчика для реализации своей идеи. Но идет неделя за неделей, а приложение по-прежнему нуждается в доработке. Как-то незаметно появляются новые функции, и масштаб задачи понемногу расширяется.
Складывается ощущение, что проект зажил собственной жизнью и пытается сожрать вас.
Как так случилось? Может, наняли плохого разработчика? Кто-то ошибся в планировании проекта? А вдруг сама идея проекта была ужасной?
Возможно. Но часто проект бывает с самого начала обречен на провал из-за недопонимания одного важного момента.
Мы предполагаем, что продукт определяется набором функций, записанных на листочке бумаги: иногда что-то добавляется, иногда убирается — но масштаб проекта всегда будто бы можно понять с одного взгляда.
Это предположение — неверно.
Проект — это не лист бумаги, не двумерный объект — у него есть глубина.
Каждую функцию на поверхности можно раскрыть — и так слой за слоем. Будь у меня склонность к громким заголовкам, я бы сказал, что всякое приложение — это лук, и нужно уметь правильно его чистить. Не очень понятно? Тогда давайте я поясню, что имеется в виду, и расскажу, почему не получается раскрывать слои приложения без слёз.
Переведено в 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
Комментарии (32)
Eldhenn
14.12.2017 09:45А как же быстрая и гибкая разработка? Как же «прототипы быстро, ещё быстрее»? Может, ещё и ТЗ надо писать? Собирать требования? IDEF0 и DFD разрисовывать, упаси боже?
vin2809
14.12.2017 11:00Может, ещё и ТЗ надо писать? Собирать требования?
Конечно, надо! Или Вы столкнетесь с проблемами определения трудоемкости, т.е. вознаграждения разработчику.
Казалось бы, что там сделал программист? Ну, написал приложение, выполняющее (по первоначальному заданию), например, 2 функции. А то, что к завершению проекта приложение выполняет уже 32 функции, для реализации которых пришлось написать еще несколько библиотек, многие могут уже и забыть (или вообще не знать)…
Поэтому, чем более проработан проект, в смысле ТЗ и прочих «бумажек», тем проще его реализовать, да и добавлять новые функции для расширения области применения.VolCh
14.12.2017 13:11Добавлять новые функции как раз сложнее при наличии полного ТЗ на продукт. Рано или поздно при добавлении окажутся противоречащие друг другу пункты и хорошо, если разработчик это заметит и спросит а каким руководствоваться. А трудоемкость можно не оценивать, а вознаграждать по факту.
aamonster
14.12.2017 15:40На нижнем уровне — можно и по факту. Но заказчик хочет сроки и цену => менеджеры хотят сроки => тимлид хочет сроки. На каком-то уровне надо всё оценить.
Hokum
14.12.2017 11:02Чем-то напоминает сравнение Waterfall и Scrum :)
algotrader2013
17.12.2017 21:21Скорее даже Waterfall и Agile. Причем, это первая статья, из тех, что я видел, где опускают Agile и превозносят Waterfall. Во всех остальных было наоборот.
Hokum
18.12.2017 00:36Кто-то должен был :) Последнее время я склоняюсь к мысли, что если команда отличная, то какую методологию не выбери — результат будет хорошим. :)
И выбор методологии не должен быть не на основании ее «модности», а из расчета что больше подходит для конкретного проекта. Мне видится, что если есть конкретная цель, конечный набор функциональности, то можно работать по Waterfall. А если такого понимания нет или цель достигнута не может быть в принципе, то Agile. Хотя для получения минимальной рабочей версии продукта можно воспользоваться Waterfall.
Нужно быть гибкими и подстраивать процессы под текущие нужды, а не нужды под процессы. :)
P.S.
А еще мне кажется, что Agile/Scrum — это просто каскад маленьких Waterfall :)
PVoLan
14.12.2017 16:53А это мы еще даже не начали писать код. Ведь на техническом уровне каждая такая «функциональность» углубляется еще примерно на столько же: использовать библиотеку или самописный код? Какие классы, модули, функции у нас будут? Какую версию ОС мы планируем поддерживать? Храним на диске или в памяти? Что именно мы храним на диске, в каком формате и почему? Как реагирует сервер, если мы пришлем ему запрос на несуществующую книгу? Long, Int или GUID? Табы или пробелы…
samizdam
15.12.2017 08:46А вот тут и проявляется технические экспертиза и опыт: Знать библиотеки под основные задачи, иметь навык проектирования api, знать стандартные протоколы и т.д.
vikarti
15.12.2017 16:29А собственно что есть книга?
Что является идентификатором книги? Название? Но как быть с разными изданиями? (Пример — Люди как боги Сергея Снегова имеют минимум 2 официальных издания, старое советское без третьей части — ее еще не было). ISBN? А нет у многих старых книг его.
А ведь бывают книги у которых реально много редакций.
И где мы будем брать список книг? C Goodreads будете брать? Ну ну удачи — там хватает книг где не заполнено поле тип редакции:Paperback/Hardback а также есть книги у которых тип — ebook хотя с данным ISBN и названием есть печатная книга (за что надо сказать спасибо тем альтернативно-умным товарищам кто использует один ISBN и для печатной и для электронной версии).
И кстати мне как пользователю приложения скажут что речь именно про печатные книги? После того как возьмут деньги за подписку? А то ведь оно не очевидно. Если электронные книги поддерживаются то как именно? Просто игнорируем проблемы с авторскими правами? Используемую какую то особенность конкретной DRM-системы? Используем тот же способ который ReDigi пробовала для легального обмена MP3?
balexa
14.12.2017 17:49Статья оставила неизгладимое впечатление, что аджайл поколение убер-стартап-веб-разработчиков начало открывать для себя водопадную модель разработки.
Arlekcangp
15.12.2017 19:03Да похоже так оно и есть. Вот только до менеджеров это докатиться еще через эпоху.
aamonster
Казалось бы, всё это хорошо известно любому, кто хоть раз пытался оценить время разработки...
aquamakc
Это всё хорошо известно разработчику, но очень часто не известно заказчику.
Такие статьи нужны, пусть они дублируют друг друга. Если есть шанс, что очередной менеджер прочитает и наконец поймёт как всё устроено «под капотом» процесса разработки, то я готов видеть подобные статьи хоть раз в неделю.
aamonster
Менеджер… Самому бы понять. А то спросят тебя — когда сделаешь то-то — а ты бекаешь, мекаешь и ответить не можешь. И не сможешь, пока не спроектируешь систему — а это может быть половина работы.
aquamakc
Заметил, что с опытом развивается некоторая «чуйка», которая позволяет более-менее на глаз определять сколько займёт времени определённая задача. Даже с учётами возможных форс-мажоров.
Не могу это объяснить природу этого факта, но тем не менее — имеет место быть.
aamonster
Природа-то понятна — "с опытом".
Но для компенсации — достаются более сложные задачи, которые и оценивать сложнее :-)
saboteur_kiev
Именно поэтому 20-летние сеньоры вызывают вполне адекватную ухмылку. Потому что изучить язык и функции в принципе по силам многим, а набраться опыта для грамотной оценки и решения сложных задач за пару лет — никак.
drondez
Как показывает практика это даже не всегда знакомо тех-лиду