Как именно следует есть слона по кусочкам?
Как известно, есть слона нелегко: его и в рот не засунешь, и не пожуешь. Народная мудрость говорит — надо есть слона по кусочкам. Это крайне ценный метод, но вопросы, тем не менее, все равно остаются. На какие кусочки делить? С каких начинать? Что оставить на потом? Какова на вкус слонятина?
Понятное дело, слон — это наш проект, большой и «неподъемный», а съесть слона означает выполнить этот проект. В прошлый раз я говорил о том, как упорядочивать кусочки работ, если исходить из вероятных изменений в проекте, и сравнивал с тем, как это происходит в «классическом» подходе. Это только половина идеи, также очень важен и принцип деления на маленькие задачи.
Вернемся на секундочку назад, к «классике». Итак, мы собираем данные, проводим анализ и пишем спецификацию. Кроме того, мы составляем диаграмму Гантта и связываем некоторые задачи end-to-begin связями, чтобы сохранить причинно-следственные связи здравого смысла.
Обратимся к википедии:
Спецификация — (позднелат. specificatio, от лат. species — род, вид, разновидность и facio — делаю) инженерный термин, обозначающий набор требований и параметров, которым удовлетворяет некоторая сущность. К примеру, мост через реку удовлетворяет таким параметрам, как максимальный общий вес нагрузки, максимальная нагрузка на ось, максимальная скорость ветра и т. д.Согласно определению, приведенному в Единой системе конструкторской документации (ЕСКД), спецификация — основной конструкторский документ, определяющий состав сборочной единицы, комплекса, комплекта. В спецификации содержится подробное перечисление узлов и деталей какого-либо изделия, конструкции, установки и т. п., входящих в состав сборочного или монтажного чертежа.
Согласно определению, приведённому в Политехническом словаре, спецификация — выполненный в форме таблицы документ, определяющий состав какого-либо изделия. Содержит обозначения составных частей, их наименования и количество.
По-моему, это прекрасный кандидат в принципы разделения слона на кусочки.
Как это выглядит для программного обеспечения? Собрали требования, тщательно обдумали. Обнаружили характерные закономерности, сущности, проступают слои, выстраивается какая-то модель данных... Строится архитектура решения, в первом приближении, состоящая из макро-частей, они описываются. Потом каждый кусок надо рассмотреть отдельно, вероятно, тоже построив для него аналогичную декомпозицию, описать его в деталях, по сути это рекурсивный процесс, анализ продолжается до достижения нужной степени детализации.
Для нужд анализа есть, например, семейство методологий IDEFX, в которой ажно 14 типов диаграмм для отображения разных аспектов устройства системы, или, например, UML, где их на данный момент 12, это не считая всякой мелочевки вроде DFD или ERD диаграмм. Анализ, вообще, интересная тема, но об этом как-нибудь в другой раз. В этот раз про эти диаграммы и методы анализа нам нужно только знать, что составлять их очень долго и дорого.
В итоге появляется на свет что-то, например, такое:
(я понятия не имею, что это за проект на самом деле — я нагуглил эту картинку, она показалась мне подходящей)
Откуда появляются эти элементы? Ведь ни одни бизнес-требования не будут описывать архитектуру решения, да и зависеть она будет от конкретного языка, технологии. Дело в том, что требования «вертикальны», а решение «горизонтально». Сейчас я объясню.
Представим себя на секундочку генератором бизнес-требований. То есть, человеком, далеким, вероятно, от конкретных технологий, но близким к бизнесу. И вот он, вооруженный своими знаниями, описывает, как он собирается заработать деньги. Точнее, это он в уме все держит, а описывает то, как должен работать продукт. Например, так: вот у нас есть пользователь, и он в нашей системе может поискать отель, выбрать подходящий и забронировать его на определенный период.
Теперь мысленно перенесемся в тело аналитика. Вот он это слышит, и, конечно, в этом сценарии появляется масса вопросов. Например — как именно выбирать отель? Как именно пользователь будет бронировать, как оплачивать? Надо ли регистрировать? Как убедится, что емейл настоящий? Как убедиться, что места есть, и что двое пользователей не займут один номер? Ну и так далее. Из одного предложения получается несколько страниц описания. Но зато вроде бы теперь все понятно.
И вот, наконец, программист, а точнее архитектор, читает все это, и, наметанным взглядом, замечает, что явно у нас есть сущности Пользователя и Отеля, возможно — Каталога Отелей, есть Резервация, есть Оплата... Во всей идее ООП — это будут отдельные классы системы. Будет вот такой класс — Пользователь, а методы у него будут, например, Зарегистрироваться, Выбрать Отель, Зарезервировать, Оплатить.
Мне очень хочется обратить внимание на эту магию — из набора историй, тщательно причесанных и уложенных одна к одной, мы вырезали части, относящиеся к Пользователю, и записали их вместе (не забыв, конечно, о взаимоотношении с другими сущностями). Вот в этом месте из набора «вертикальных» историй у нас получаются «горизонтальные» слои абстракций — View, Controller, Model, например. Или вот то, например, что на картинке нарисовано — вот эти прямоугольнички абстракций. Каждая из исходных историй работает, затрагивая многие из них, едва ли не все.
И вот эти прямоугольнички на диаграмме и выглядят как кусочки, которыми надо есть слона. Вот они, продуманные, нарезанные, удобные. Где подвох?
Подвох, как обычно, в готовности к изменениям.
Дело в том, что вот эта конверсия «вертикальных» историй в «горизонтальную» архитектуру является сложной, практически творческой операцией. Как мы знаем, собрать вообще все требования в начале разработки — это непозволительная роскошь в наше быстрое, если не сказать суетное, время. Но еще важнее то, что входной набор историй будет меняться, и надо быть готовыми к изменениям. Беда в том, что нет прямой связи между историями и архитектурой, то есть изменения в историях не приводят к изменениям в архитектуре. Анализ, декомпозицию и все эти вещи, вообще говоря, придется делать заново при каждом изменении.
Теперь самое опасное: если делать проект по кусочкам из этой абстракции, а потом окажется, что ее надо переделывать, то все, что мы сделали, вероятно, придется выкинуть. Ну, конечно, в реальности не так все трагично, многое можно будет использовать. Но в общем случае — это может быть очень большая и неприятная вещь в проекте. Вплоть до того, что изменение будет стоить ТАК дорого, что приходится «подтесывать» бизнес-модель...
Что нам предлагает agile на этот счет?
Во-первых, спецификация — мы больше не делаем ее, я имею в виду большой всеобъемлющий документ. Взамен мы имеем набор user stories разной степени детализации, и они, как вы помните, тщательно приоритизированы. Те, что в самом верху, и, соответственно, пойдут в разработку уже вот-вот, детализированы подробно. Те, что не так приоритетны — в общих чертах. Те, что совсем далеко — и вовсе обозначены условно. Выгода тут такова: не делать анализ для тех историй, которые делать еще не скоро, а, учитывая нашу тягу к изменениям, вероятно, никогда.
Во-вторых, user stories — это «вертикальные» истории, они не портятся от изменений. Может быть, частично теряют актуальность, может быть — местами меняются, но не «тухнут» все разом от изменений в требованиях.
В-третьих — это то, что мы и делаем их «историями». То есть, для того, чтобы реализовать user story нам приходится спроектировать изменениях во всех прямоугольничках нашей архитектуры. Добавить кое-что в базу данных, изменить модель, дописать пару контроллеров, несколько новых вьюшек.
В-четвертых, user stories устроены так, что их выполнение приносит конкретный бизнес-смысл, то самое business-value. Это означает, что его уже можно отправлять пользователям. Это работающие истории. Если бы мы разработали сперва весь уровень базы данных, по спецификации, то у нас была бы шикарная база данных, но, к сожалению, она не нужна нашим пользователям. У нее нулевой business value.
В-пятых, с каждой итерацией мы знаем все больше о проекте, и делаем анализ и архитектурные решения значительно точнее (и быстрее, кстати). Качество вертикально-горизонтального (то есть, анализа и архитектурных решений) преобразования все выше и выше с каждой итерацией, и уж конечно выше, чем в самом начале проекта, когда мы про него, фактически, почти ничего не знаем.
Как это сделать? Мы просто делаем анализ и проектирование каждый раз, в каждой итерации разработки. Для тех историй, которые в нее войдут. То есть — не для всех, значит, это не будет так долго и дорого. Но как быть с тем, что новые истории будут рушить старые, уже сделанные? Что ж, возможно их придется также изменять или даже переписывать. Зная это с самого начала — мы не строим архитектуру «на века» и потенциально готовы менять ее. Это в любом случае дешевле, чем переписывать вообще все.
Подводя итог, и возвращаясь к слоновой теме: так в чем же разница в подходе?
В одном случае мы воспринимаем аналогию буквально, и делим слона на части — сначала переднюю правую ногу, потом хобот, потом хвост, потом левую заднюю... Во втором случае мы делаем то, что с физическим объектом слоном вообще-то невозможно сделать. Мы делим его на сотню маленьких слонов, у каждого из которых есть и ноги, и хвост, и хобот, и все остальное, в частности — бизнес-ценность: один умеет трубить, второй — шевелить хоботом, третий — есть.
Подумайте, с чем вы хотите остаться в случае внезапных изменений.
20 коментарів
Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.