Терминология занимает важное место в любой методологии или процессе разработки, потому что она позволяет участникам лучше понимать друг друга и оперировать едиными понятиями и терминами. Неточная терминология приводит к недопониманиям и разногласиям. Я бы хотел обсудить два термина, которые всегда вызывали у меня странное ощущение неприятия: нефункциональные требования и приемочный критерий.
Начнем с нефункциональных требований. Во-первых сразу хотелось бы отметить, что сами по себе они очень важны. Но из-за специфического названия многие склонны о них забывать. Часто заказчики даже не понимают о чем идет речь: «Нефункциональные требования? Нам в первую очередь нужен качественно сделанный функционал!». Мне гораздо больше нравится понятие «качество сервиса» (quality of service). Ведь качество всегда является важным фактором и его нельзя игнорировать. В это понятие входит доступность, надежность, производительность, расширяемость, устойчивость и так далее. При такой формулировке нефункциональные требования превращаются в качественные показатели системы. Если задать вопрос заказчику об его ожиданиях от качества разрабатываемого продукта, то он с радостью поделится с вами, так как вопрос будет ему понятен и важность его будет действительно высока.
Второй термин, который хотелось бы обсудить – это приемочный критерий. На первый взгляд с ним все нормально. Заказчик или «владелец продукта» (Product Owner) формулирует приемочные критерии для каждой новой функциональности системы, после чего они используются для написания приемочных тестов, модульных тестов, интеграционных тестов, а также приема готового функционала. Но что если заказчик не готов придумывать и выставлять приемочные критерии? Что если фаза приема нового функционала вообще отсутствует на проекте? В этом случае теряется смысл слова «приемочный» и многие попросту начинают игнорировать приемочные критерии, тем самым лишая команду разработки важного артефакта. Мне больше по душе термины «критерий готовности» (Definition of Done) или «критерий завершенности» (completion criteria). Цель этих терминов очень похожа – указать, что необходимо сделать чтобы функциональность считалась готовой или завершенной. Добавлять критерий готовности может кто угодно: разработчик, лидер команды, менеджер проекта, тестировщик. Физически данные критерии добавляются в описание задачи в системе управления задачами или на доску задач. Для этого может быть использовано описание задачи или отдельная секция под названием «как продемонстрировать» (how to demo). Например, для регистрации пользователя в приложении могут быть использованы следующие критерии готовности:
Критерий готовности позволяет ничего не упустить в процессе разработки функциональности и является источником для тестов. В случае использование формального приема функциональности заказчиком эти же критерии могут быть успешно использованы.
Используйте такую терминологию, которая будет понятна всем в вашей команде и за ее пределами!
Очень часто мы говорим о качестве кода, о необходимости писать код правильно, использовать инженерные практики и шаблоны проектирования (design patterns) . Но как качество кода отражается на бизнесе? Какими последствиями чреват низкокачественный код? Давайте разберем эти вопросы на примере одного проекта.
На начальной стадии проекта необходимо осуществить планирование релизов (как минимум одного). Это требуется для того, чтобы планировать развитие бизнеса, принимать решения по различным финансовым вопросам и по многим другим причинам. В идеальном случае, при Agile планировании опытной командой, берется в расчет продуктивность команды и оценки сложности необходимой функциональности.
И вот начинается разработка. Чем больше кода разрабатывается, тем сложнее он становится для понимания и использования. Код плохого качества усугубляет ситуацию наличием множества дубликатов, мелкими ошибками, различиями в дизайне и стиле, огромными кусками неструктурированного кода, невнятными названиями методов и переменных, глубиной вложенности логики и так далее. Вдобавок не всегда присутствуют модульные тесты и код незадокументирован. Таким образом добавлять новый код в систему или изменять старый код становится все сложнее и сложнее. А это не может не отразиться на продуктивности работы членов команды. Естественно продуктивность падает.
Почему же команда не уделяет внимания проблемам с кодом? Все дело в том, что у команды не хватает на это времени (часто также не хватает опыта и знаний) – ведь нужно разрабатывать новую функциональность. Накопление проблем в коде называется техническим долгом (technical dept). Чем больше долг, тем тяжелее жить с ним. Если же продуктивность команды падает в результате возросшего технического долга, то команда начинает не успевать завершить новый функционал и начинает торопиться еще больше. Образовывается замкнутый цикл. Чем больше команда торопится, тем меньше времени уделяется качеству кода. Чем меньше времени уделяется качеству кода, тем больше технический долг. А чем больше технический долг, тем меньше продуктивность и тем меньше успевает команда выполнить в срок. И, как следствие, начинает еще больше торопиться.
Через определенное время сторона бизнеса начинает понимать, что команда не успевает все выполнить в запланированный срок. Если используется Agile подход, то это станет видно гораздо раньше, чем при применении классических подходов. И тут необходимо что-то предпринять. Очень часто принимается решение расширить команду разработки (конечно, если хватает бюджета). Чем больше становится разработчиков, работающих над тем же кодом по тем же принципам, тем хуже его качество. Кое-как система доживает до успешного релиза и ее начинают использовать.
Разработка продолжается и появляется необходимость поддерживать систему. Пользователи находят множество проблем, требующих мелких доработок и исправлений. Изменения в коде даются очень тяжело. Продуктивность падает еще больше. И тут кому-то в голову приходит гениальная мысль – пришло время переписать ядро системы заново, переделать архитектуру, сделать новый дизайн и решить раз и навсегда все проблемы. Остановить работу над новой функциональностью нельзя, потому что это грозит бизнесу крахом. Поэтому выделяется небольшая команда для реализации идеи новой архитектуры. Обычно такая команда состоит из опытных разработчиков.
Начинается трудоемкая работа по дизайну, анализу проблем текущей системы и разработке новой архитектуры. После чего происходит миграция функциональности. Но основная команда разработки тоже не стоит на месте, а продолжает разрабатывать код для старой системы. Его становится все больше, а значит, разбираться в нем становится все труднее. Это начинает замедлять команду разработки новой архитектуры, так как весь свежий функционал необходимо перенести. Процесс превращается в бесконечную гонку. Ситуация усугубляется тем, что часто причиной проблем считается не качество кода, а лишь архитектурные и проектировочные решения. Благодаря этому новый код получается того же уровня качества и вскоре начинает страдать от тех же проблем, что и его предшественник.
В итоге новая система поставляется, но с урезанной функциональностью или же гораздо позже запланированного срока. При этом качество кода в ней опять оставляет желать лучшего и все проблемы, описанные ранее, появляются вновь. За время разработки сменились многие члены команды, и кому-то снова приходит идея переписать все заново (мы все считаем, что можем сделать лучше других). Процесс продолжается до тех пор, пока не закончится бюджет или же не лопнет терпение у стороны бизнеса.
Вот к таким последствиям может привести плохое качество кода. Для того, чтобы этого избежать, необходимо предпринимать ряд упреждающих мер:
Следите за своим кодом и вы сможете избежать многих проблем!
Я думаю, что вопрос “А ты завершил свою задачу?” вы слышали и сами задавали неоднократно. К сожалению, понятие завершенности у всех разное. Это может причинить большие проблемы в процессе разработки. Задачи, закрытые с разным уровнем завершенности, зачастую становятся причиной найденных ошибок, проблемного кода, неверных дизайнерских решений и других неприятностей. Чтобы избежать такого рода ситуаций команде стоит собраться и обсудить командное определение завершенности (Definition of Done). Для разного типа задач такое определение может отличаться. Лучше всего оформить определение завершенности и поместить его в общедоступное место: на доску задач, на WiKi, на стол каждому члену команды. После определения критерия завершенности задача может считаться законченной только в случае полного удовлетворения всем пунктам критерия. Каждая команда может включать свои пункты, которые зависят от языка программирования, специфики проекта, состава команды и других факторов. Вот один из примеров определения завершенности:
Но это еще далеко не все! В Agile подходах используется итеративный и инкрементальный стили разработки. Это значит, что заказчик в праве ожидать некоего набора завершенной функциональности к концу каждой итерации. Но ваше понимание завершенности может очень сильно отличаться от понимания заказчика. Чем больше разница, тем больше накапливается недоделанной работы. Очень хорошо, если вы демонстрируете завершенные задачи в конце каждой итерации, причем демонстрируете так, как просит вас заказчик. В этом случае проблема очень быстро вылезет наружу. Для того, чтобы избежать проблем, нужно добавить в определение завершенности пункты от заказчика (синхронизировать список с ним). В этом случае заказчик знает чего он в праве ожидать и как он может проверить готовность функционала.
Давайте рассмотрим небольшой пример. Ваша команда имеет отличный, продуманный критерий завершенности задач, но туда не входит интеграция и установка задач на рабочий сервер, а также регрессионное тестирование. Итерация заканчивается и вы радостно показываете новый функционал заказчику на специальном тестовом сервере. Все проходит отлично и заказчик задает вопрос: “Ну что с завтрашнего дня пользователи смогут оценить новую функциональность, а мы – получить больше прибыли?”. В ответ вы чешете голову и отвечаете, что нужно еще неделю для того, чтобы установить все на рабочий сервер, написать скрипты обновления базы данный, мигрировать данные с нескольких старых табличек, прогнать все регрессионные тесты. Естественно это может расстроить вашего заказчика и обмануть его ожидания. Синхронизация критерия завершенности на ранних этапах разработки поможет построить доверительные отношения и убережет от многих неприятностей.
Критерий завершенности можно использовать еще для одной интересной цели – выделение стадий, через которые проходит ваша задача. Это позволяет построить более правильную Kanban доску задач и расставить ограничения на объем работ, выполняемый одновременно. К примеру, можно придти к таким колонкам: “Написание приемочных тестов”, “Реализация”, “Code Review”, “Тестирование”, “Установка на сервер”. В этом случае у команды и заказчика будет общее понимание почему нужны все эти стадии и как далеко конкретная задача находится от состояния завершения. Гораздо легче отслеживать прогресс и анализировать проблемы.
Всегда старайтесь закончить задачу так, чтобы вы могли собой гордиться!
В продолжение запланированных на начало июля “выходных тестировщика” мы решили организовать подобное мероприятие и для разработчиков. Назвали его по аналогии – “выходные разработчика”. Мероприятие состоится 17-18 июля и будет посвящено различным инженерным практикам.
В субботу 17 июля будет проведен тренинг “Инженерные практики в Agile”, на котором участники за 8 часов познакомятся с 6 инженерными практиками (Continuous Integration, Code Review, TDD, приемочное тестирование, парное программирование, рефакторинг), пообщаются с профессионалами отрасли на тему их внедрения и поддержки, а также смогут получить ответы на наболевшие вопросы из жизни разработчика в Agile проекте.
В воскресенье 18 июля запланирован тренинг “Continuous Integration на практике”. Этот тренинг дает достаточно знаний и начального практического опыта для того, чтобы начать внедрение одной из наиболее полезных инженерных практик на уровне проекта или целой компании. По опыту предыдущих проведений мы немного переделали тренинг, чтобы упростить настройку и конфигурацию для практической части, тем самым оставив участникам больше времени для обучения на практике.
Программа до конца еще не закончена. Пишите нам о своих пожеланиях и мы дополним программу необходимыми и востребованными тренингами.
Регистрация на тренинги мероприятия уже открыта и продлится до 10 июля. Торопитесь, количество мест ограничено! Присоединяйтесь к нам, эти выходные принесут вам немало пользы в будущем!
Зарегистрироваться на тренинги можно на нашем сайте. Стоимость участия 800 гривен за каждый из тренингов. В оплату любого тренинга входит обед и кофе-паузы. При регистрации сразу нескольких участников (не менее 3) скидка 10%.
Ждем вас на наших тренингах!
Мы рады сообщить о том, что наши возможности по проведению тренингов и состав доступных тренеров расширились благодаря сотрудничеству с российским тренинг-центром ScrumTrek. Многие отлично знают по выступлениям на различных конференциях Асхата Уразбаева и Никиту Филлипова. На последней конференции Agile Base Camp в Киеве Асхат выступил с докладом “Применение Lean в Offshore разработке”, а Никита – с мастер-классом “Формируем и Приоритезируем бэклог используя StoryMapping”. Мы слышали очень много положительных отзывов от участников и решили организовать первый открытый тренинг Асхата Уразбаева в Киеве. Состоится мероприятие 3 июля и посвящено будет разработке с использованием Scrum (“Agile Development with Scrum”).
Данный тренинг будет интересен для тех, кто планирует внедрять Scrum в своем проекте или организации, а также для тех, кто хочет сравнить свои способы работы с лучшими практиками индустрии. На тренинге будут рассматриваться следующие темы:
Тренинг будет насыщен примерами, дискуссиями, играми, иллюстрирующими основные принципы и практики гибкой разработки. Он направлен не только на формирование базовых представлений о гибких методологиях разработки, но и на упорядочивание имеющихся знаний и навыков. После прохождения тренинга участники смогут аргументированно пытаться внедрить у себя на проекте различные Agile практики и подходы, а также получат толчок к дальнейшему развитию в мире современной разработки, где Agile методологии давно вышли на первый план.
Регистрация на тренинг уже открыта и продлится продлится до 28 июня. Стоимость участия: при регистрации до 20 июня – 1000 гривен, после 20 июня – 1200 гривен. Торопитесь, количество мест ограничено! Если у вас есть вопросы по организации тренинга, то мы с радостью ответим на них. Для этого отправьте свой вопрос на support@xpinjection.com.
Очень часто поднимается вопрос о применении Agile в больших командах размером более 30 человек. Как известно, Agile методологии рекомендуют работать небольшой командой, желательно расположенной в одном месте. Это очень сильно упрощает коммуникации и позволяет успешно применять большую часть Agile практик. Но при разработке действительно большой системы не всегда можно справиться маленькой командой. Есть проекты с командами более 100 человек. Можно провести аналогию с программированием больших систем. Если у нас есть небольшая по функциональности система, к которой нет жестких требований по расширяемости и отказоустойчивости, то логично реализовать ее единым модулем. При этом возможно разделение на слои для облегчения тестирования и разделения логики. Архитектуры подобных систем очень простые и похожи друг на друга. Это очень напоминает работу небольшой команды. Когда же нам нужно разработать систему с серьезной бизнес логикой, работающую с внешними сервисами, имеющую высокие требования к расширяемости и отказоустойчивости, интегрирующуюся с различными устройствами и обрабатывающую огромные потоки информации, то все значительно усложняется. Тут на помощь приходит компонентная архитектура, асинхронное общение между компонентами, сервисно-ориентированный подход и т.д. Архитектура такого рода систем достаточно непроста и требует тщательного анализа, чтобы не только удовлетворять текущим требованиям, но быть достаточно гибкой и расширяемой. Именно из такого рода архитектур можно позаимствовать приемы организации работы больших команд.
Первый прием для построения компонентной архитектуры – это выделение полноценных компонентов. В случае большой команды такими компонентами являются маленькие подкоманды. Каждая подкоманда имеет все необходимое для независимого существования. У нее есть все нужные ресурсы, как человеческие, так и технические. В такой подкоманде можно сравнительно легко использовать любой понравившийся Agile процесс разработки. Для того, чтобы компонентная архитектура работала, у каждой компоненты должна быть четко очерченная зона ответственности. В случае подкоманды речь идет о части разрабатываемой системы. Для правильного выделения подкоманде ее зоны ответственности необходимо учесть, что компоненты должны быть максимально независимыми.
Это сразу делает проигрышным разделение по слоям (база данных, уровень доступа к данным, сервисная логика, пользовательский интерфейс). В этом случае зависимости слишком сильные, что влияет на коммуникации, планирование и остальные части процесса разработки. Разделение по слоям работает в проектах среднего размера, когда из-за специализации членов команд и их распределения тяжело выделить полнофункциональные подкоманды. В этом случае команды в каждой итерации анализируют точки соприкосновения и выделяют интерфейсы взаимодействия. В процессе разработки функционала используются техники заглушек и простых реализаций для обеспечения ранней интеграции. Второй вариант – это разделение по архитектурным компонентам системы. Этот вариант возможен при хорошей архитектуре самой системы, но таит в себе скрытые опасности. К таким опасностям относятся локализация архитектурных знаний, узкая специализация команд, распределенное планирование и т.д.
Второй прием – это обеспечение коммуникации между компонентами. Компоненты в архитектуре должны общаться только со своими ближайшими соседями, причем протокол может быть синхронный или асинхронный. В случае с синхронным протоколом (когда компоненты достаточно сильно зависят друг от друга) может применяться совместное планирование итерации, ежедневная синхронизация посредством проведения собрания представителей команд (Scrum of Scrum в методологии Scrum). В случае асинхронного протокола можно использовать Kanban подход. Если одной подкоманде необходимо, чтобы определенный функционал был реализован другой подкомандой, она помещает запрос на эту функциональность в очередь ожидания. Эта очередь может позволять управление приоритетами. Статус заявки можно отслеживать на Kanban доске по мере прохождения всех стадий разработки. Замеряя время цикла от постановки задачи в очередь до ее выполнения, можно добиться более точного планирования для зависимых задач.
Кардинально другой способ взаимодействия компонентов применяется в событийной архитектуре. Каждый компонент, в том числе и заказчик, может генерировать события определенных типов (задачи на реализацию определенного функционала). Все задачи поступают на общую шину. Это может быть система управления задачами или же физический инструмент визуализации (в отсутствии проблем с распределенной командой). Каждый компонент способен обрабатывать определенные типы задач, что зависит от его роли в системе. Таким образом, подкоманда всегда берет из шины задачи с максимальным приоритетом, которые она способна делать. Как только задача закончена, ее результаты публикуются в общедоступном месте либо же попадают обратно в шину в качестве задачи другого типа.
Анализируя возможности и ограничения работы в конкретном проекте, с помощью аналогий из мира архитектуры можно придти к стройному и продуктивному Agile процессу в большой команде. Ниже приведен пример такого рода процесса:
Как видно из приведенных примеров, архитектуры современных систем таят в себе очень много интересных идей, которые можно использовать для организации процесса разработки в большой Agile команде. Ведь многие из существующих больших систем действительно работают! Я готовлю детальный доклад на эту тему, с которым планирую выступить на ближайшей конференции. Надеюсь с помощью идеи поиска аналогий в архитектуре вы сможете улучшить свой процесс разработки.
Видео презентация “People factor as failure reason of Agile adoption” от Алименкова Николая с конференции Agileee 2009 доступна в видео секции.