Как далеко вы должны разрезать по вертикали?

Мы небольшая команда из 4 разработчиков программного обеспечения, пытающихся использовать Scrum. У нас есть большой проект, который нужно начать с нуля, и мы столкнулись с препятствием, связанным с нарезкой проекта.

Проект представляет собой распределенную систему с множеством различных компонентов:

  • База данных SQL-сервера
  • Пара веб-сервисов, реализующих OAuth 2.0 (которые мы запускаем сами)
  • Веб-сервис аудита
  • Веб-сервис FHIR (в конечном итоге)
  • Серверные модули (сборки .NET)
  • Одностраничное приложение (SPA) на основе JavaScript
  • Модули на основе JavaScript, размещенные в SPA
  • Наш собственный JavaScript-фреймворк для создания модулей SPA.

Наш первый PBI кажется таким простым: пользователь может войти в систему, используя свою смарт-карту.

Теперь проблема заключается в том, чтобы использовать эту пользовательскую историю для вертикального среза, как это рекомендуют почти все советы по Agile: мы нарезаем всю систему?

Если мы это сделаем, кажется, что мы откусили монументальную сумму; нам нужно будет реализовать все поведение OAuth, включая проверку разрешений, большую часть инфраструктуры JS (обработка HTTP, шаблоны и привязка данных), основы SPA и всю структуру базы данных и логику SQL, которая требуется только для поддержки этого.

Если мы хотим рассматривать каждый PBI как доставляемую единицу, которая обеспечивает ценность для пользователя, похоже, нет способа разбить это на части.

Я так много читал об этом, но все примеры относятся к гораздо меньшим и более простым приложениям.

Может быть, мы просто слишком жестко интерпретируем Scrum?

Похоже, ваша команда обнаружила, что включение «Пользователь может войти в систему с помощью своей смарт-карты» в Журнале Спринта в своем первом Спринте было бы плохой идеей. Это хорошо! Так что не делай этого.

Ответы (3)

Вам это понадобится, но не сразу

Таким образом, смысл вертикального среза состоит в том, чтобы взять что-то вроде базы данных и точно сказать: «Мне не нужна вся база данных прямо сейчас». Итак, давайте подтвердим ваше утверждение: вам нужна база данных?

Давайте проясним, что делает база данных: она распределяет изменения состояния по нескольким серверам и сохраняет эти изменения при перезапуске сервера. Если вам нужна простая сохраняемость, но не распространение, вы можете записать в локальный файл JSON или около того. Если вам нужно распространение, но не постоянство, вы можете сделать так, чтобы узлы передавали сообщения друг другу, например, с помощью ZeroMQ.

Я не вижу ничего в вашей первой пользовательской истории о каком-либо количестве параллельных серверов, и я не уверен, что вижу что-либо в вашей первой пользовательской истории о каком-либо постоянстве; возможно, вы сможете мириться с поведением в памяти по умолчанию: «когда мы развертываем новую версию программного обеспечения, все выходят из системы, а все внесенные ими изменения сбрасываются».

Так что вам не нужна база данных. Вам может понадобиться (если у вас есть список, сопоставляющий некоторые токены смарт-карт с каким-то внутренним именем пользователя) некоторый статический файл JSON (неясно, следует ли его зафиксировать в репо или просто файл конфигурации, распространяемый по электронной почте/Slack и копируемый как последняя часть инициализации; если вы не возражаете против сохранения данных в репозиторий, их можно даже сохранить в один из ваших исходных файлов, анализ JSON/чтение файла не требуется).

Точно так же вам нужен большой Javascript SPA? Я так не думаю — вам может понадобиться кард-ридер или HTML-форма, в зависимости от того, аппаратный токен, отображающий какие-то цифры, или что-то более интересное.

Вам нужна структура разрешений? Нет, единственное разрешение, охватываемое вашей пользовательской историей, — «может войти в систему с именем пользователя и смарт-картой, связанной с этим именем пользователя», и это глобальное разрешение.

Когда вы разрезаете по вертикали, вы сводите каждый слой только к подмножеству функций, необходимых для работы пользовательской истории. Вы не пытаетесь предоставить одну двадцатую часть базы данных и одну двадцатую часть структуры разрешений просто потому, что у вас есть двадцать пользовательских историй, и вы пытаетесь предоставить одну из них. Вы часто можете обнаружить, что на ранних этапах несколько слоев пусты.

Используйте отложенную функциональность, чтобы получить лучшие бизнес-требования

На самом деле вы должны желать этого. Я настоятельно рекомендую вам отложить создание базы данных как можно дольше , то есть до тех пор, пока у вас не появятся настоящие пользователи, которые будут раздражаться как из-за простоя, так и из-за того, что их изменения не сохраняются после перезапуска сервера. Для этого есть очень важная причина: нисходящий дизайн обычно близорук. Вы хотите иметь возможность, прежде чем лишить себя свободы возиться со структурами данных, заставить реального пользователя возиться с бизнес-логикой вашего инструмента и сказать вам что-то вроде этого:

"О, нет! Вы предполагаете, что у каждого заказа на покупку есть контракт, но это неверно, у нас на самом деле есть прототипы, которые являются экспериментальными, чтобы попытаться получить контракт... Мы регистрируем заказы на покупку для них, чтобы построить их, но они не являются частью какого-либо контракта».

«Да, это не было частью нашей первоначальной спецификации. Есть ли у вас общий термин, который охватывает как прототипы, так и контракты, чтобы я мог показать вам список _____, а затем столбец с надписью «тип = прототип» и «тип = контракт»? Как будет называться этот список?»

«О да, мы просто называем их все проектами».

А затем вы переписываете свою внутреннюю структуру данных, чтобы заказы на покупку принадлежали проекту, который может иметь type=Prototypeили type=Contract, если вы не получаете достаточно различий между ними, чтобы вам нужна таблица прототипов и таблица контрактов, для которых проект использует внешний ключ.

Дело в том, что если вы не будете откладывать создание базы данных до тех пор, пока не получите эту обратную связь, то под давлением вы начнете получать очень бородавчатую базу данных:

«Э-э, почему у этих Контрактов все эти нулевые значения? Мы просто забыли их сделать NOT NULL

"Может быть. У них есть номер для своего prototype_id?

"Ага..."

«Посмотрите, что база данных называет контрактом, на самом деле то, что пользовательский интерфейс называет проектом, потому что, когда мы начинали, мы думали, что все проекты были контрактами, но это не так, некоторые из них являются прототипами. Таким образом, либо все столбцы контракта должны быть нулевыми, а столбцы контракта prototype_idдолжны быть ненулевыми, либо все prototype_idстолбцы контракта должны быть ненулевыми, а столбцы контракта должны быть нулевыми».

Люди думают лучше, когда они могут взаимодействовать с системой. Особенно люди, которые предъявляют вам требования. Суть Agile заключается в том, что традиционный дизайн программного обеспечения подобен тому, чтобы попросить комитет, который ничего не знает об одежде, написать спецификацию о том, какую одежду они хотят носить, а затем мы будем производить эту одежду точно в соответствии с этой спецификацией, а затем, если они недовольные тем, как они сидят, они могут не носить их или создавать дополнительные документы, ожидая, как они изменятся. Вместо этого Agile-магазин пытается создать набор последовательных адаптированных приближений, которые всегда точно подходят клиенту, но выглядят неправильно. Поэтому они начинают со слов «хорошо, мы накинем вам на голову простыню» и получают ответ: «Хорошо, но я не вижу сквозь простыню, и к тому же она не подходит по цвету к тому, что я собираюсь сделать. Новый лист лучшего цвета с дыркой. «Нет, нужны рукава и капюшон». И так далее.

Вы можете намеренно отложить правильное выполнение важных частей функциональности, потому что вы можете неправильно понять что-то вроде «цвета», который требует значительных доработок с нуля. Это происходит все время со структурами базы данных.

Спасибо за Ваш ответ. Скажем, изначально мы не реализуем инфраструктуру SPA и JS, в какой момент мы их реализуем? Пользователю все равно, но нам, как разработчикам, очень хотелось бы, чтобы фреймворк ускорил разработку пользовательского интерфейса.
@Lee: Вы внедряете их, когда кто-то из заинтересованных сторон (может быть разработчик) начинает этого требовать. Если вы спросите конечного пользователя, он может даже не захотеть всего этого входа/разрешения.
@ Ли Что сказал Барт. Имейте в виду также, что разработчики могут многое сделать с пользовательскими интерфейсами, которые не являются SPA, например, общий список запросов Postman, к которому каждый может вернуться.

Когда у вас есть распределенная система со многими компонентами, вы можете столкнуться с такой проблемой. Я обнаружил, что хорошей отправной точкой является идея технических возможностей. У вас есть выражение потребности верхнего уровня, но вы можете создать другие элементы невыполненной работы по продукту, которые могут это сделать. Каждая из них должна иметь возможность быть спроектирована, построена, испытана и доставлена ​​независимо. Возможно, сами по себе они не удовлетворяют потребности конечного пользователя, но позволяют спланировать работу и убедиться, что у вас есть то, что вам нужно.

Будет еще лучше, если эти части технической поддержки смогут разблокировать несколько различных элементов невыполненной работы, с которыми сталкивается пользователь. В зависимости от того, какие элементы бэклога продукта представляют собой различные элементы, вы можете найти творческие способы разделения технических возможностей на определенные («нижнего уровня») компоненты, чтобы включить ряд элементов бэклога продукта, гарантируя, что они имеют разумный размер и область применения. , и доставляемый.

В зависимости от инструментов, которые вы используете для управления Журналом невыполненных работ по продукту, вы можете установить отношения и связи между работой, чтобы определить, что элемент технической поддержки «блокирует» другую работу, или соответствующим образом установить зависимости. Это может помочь в планировании и составлении графика работы, гарантируя, что все необходимое будет сделано и доставлено, когда это необходимо.

Короткий ответ: нет, не прорезайте все это, если то, что вы делаете, на самом деле не проходит через все это, а затем ограничьте его объем.

Идея вертикального среза заключалась в том, чтобы избавиться от таких элементов невыполненной работы, как «Разработка таблиц базы данных для клиентов». Если вы используете элементы невыполненной работы, которые представляют ценность с точки зрения клиента, и это касается только некоторых из них, это нормально.

Кроме того, начните с простых архитектур. Вам почти наверняка не нужны все эти вещи для поддержки ваших первых нескольких элементов невыполненной работы. Я часто удивляюсь, как далеко в программном проекте я могу приносить пользу без таких вещей, как база данных. Если мы строим приложение как слабосвязанный код или, что еще лучше, сильно развязанный код, добавление дополнительных компонентов позже, когда они нам понадобятся, не составит большого труда.