Гибкие технологии разработки ПО
Вопросы
✅ — готов
🔄 — не совсем готов
🔴 — совсем не готов
1. ✅ Чем отличается «управление продуктом» от «управления проектом»?
Проект — это деятельность, направленная на достижение уникальной цели.
Проект характеризуется тремя главными свойствами:
- Время — когда проект начинается и заканчивается
- Цель — какой результат должен быть получен к концу проекта, для чего затевается проект
- Ресурсы — какие люди, за какие деньги и как будут работать для достижения цели
Проект — не план действий, а деятельность для реализации такого плана.
Продукт — это результат деятельности, который продается, покупается и используется.
Проще говоря: проект — это процесс, продукт это результат.
Управление продуктом — определение свойств и характеристик продукта.
Управление проектом — контроль процессов, решение сложностей на этапе реализации плана.
2. ✅ Чем разработка программного обеспечения отличается от других видов деятельности?
- Все программы разные: нет типовых проектов.
- Виртуальный мир: дискретный, менее предсказуем.
- Склонность к изменениям: доработки вносятся и после сдачи проекта.
- Неидентифицируемые процессы: не всегда понятно, работает программист или нет.
- Новые сотрудники приносят пользу с задержкой: требуется несколько месяцев на ознакомление с проектом.
- Дефицит сотрудников: мало людей, много узких специализаций.
- Сотрудниками сложно управлять: следствие дефицита сотрудников и неидентифицируемых процессов.
3. 🔄 Основные подходы к организации процесса разработки программного обеспечения.
Варианты решения проблем:
-
Использование крутых инструментов (Git, VSCode, …)
1 — Обнуляется накопленный опыт
2 — Увеличивается глубина виртуализации
5 — Задержка на изучение инструментов
6 — Меньше людей умеют пользоваться
7 — Менеджеры не умеют пользоваться
-
Ковбойское программирование ("лучше кодить, а не управлять")
Иногда работает, иногда нет
Условия для успеха:
- все являются экспертами в области
- все хорошо мотивированы
- новый проект
Хватает, чтобы проскочить до первой версии, дальше становится сложнее.
-
Формализация
1 — детальная архитектура на UML, но возникает конфликт между разработчиками и архитекторами
2 — не зависим от ОС, СУБД, виртуального мира, но тонем в абстракциях
3 — подробные ТЗ + запрет изменений, но избыточные и абстрактные требования
4 — подробный ежедневный отчёт, но программисты ненавидят отчёты
5 — подробная документация, но проблемы с её обновлением и синхронизацией
7 — опционы и акции за хорошую работу
-
Waterfall — модель процесса разработки программного обеспечения, жизненный цикл которой выглядит как поток, последовательно проходящий фазы анализа требований, проектирования, реализации, тестирования, внедрения и сопровождения. Каскадная модель хорошо зарекомендовала себя при построении относительно простых ПО, когда в самом начале разработки можно достаточно точно и полно сформулировать все требования к продукту.
-
Agile — гибкие методологии, нацелены на минимизацию рисков путём сведения разработки к серии коротких циклов, называемых итерациями, которые обычно длятся две-три недели. Каждая итерация сама по себе выглядит как программный проект в миниатюре и включает все задачи, необходимые для выдачи мини-прироста по функциональности: планирование, анализ требований, проектирование, программирование, тестирование и документирование. Хотя отдельная итерация, как правило, недостаточна для выпуска новой версии продукта, подразумевается, что гибкий программный проект готов к выпуску в конце каждой итерации. По окончании каждой итерации команда выполняет переоценку приоритетов разработки.
4. ✅ Agile Manifesto и принципы гибкой методологии разработки.
Манифест Agile:
Мы постоянно открываем для себя более совершенные методы разработки программного обеспечения, занимаясь разработкой непосредственно и помогая в этом другим. Благодаря проделанной работе мы смогли осознать, что:
Люди и взаимодействие важнее процессов и инструментов
Работающий продукт важнее исчерпывающей документации
Сотрудничество с заказчиком важнее согласования условий контракта
Готовность к изменениям важнее следования первоначальному плану
То есть, не отрицая важности того, что справа, мы всё-таки больше ценим то, что слева.
Принципы:
- Наивысшим приоритетом для нас является удовлетворение потребностей заказчика, благодаря регулярной и ранней поставке ценного программного обеспечения.
- Изменение требований приветствуется, даже на поздних стадиях разработки. Agile-процессы позволяют использовать изменения для обеспечения заказчику конкурентного преимущества.
- Работающий продукт следует выпускать как можно чаще, с периодичностью от пары недель до пары месяцев.
- На протяжении всего проекта разработчики и представители бизнеса должны ежедневно работать вместе.
- Над проектом должны работать мотивированные профессионалы. Чтобы работа была сделана, создайте условия, обеспечьте поддержку и полностью доверьтесь им.
- Непосредственное общение является наиболее практичным и эффективным способом обмена информацией как с самой командой, так и внутри команды.
- Работающий продукт — основной показатель прогресса.
- Инвесторы, разработчики и пользователи должны иметь возможность поддерживать постоянный ритм бесконечно. Agile помогает наладить такой устойчивый процесс разработки.
- Постоянное внимание к техническому совершенству и качеству проектирования повышает гибкость проекта.
- Простота — искусство минимизации лишней работы — крайне необходима.
- Самые лучшие требования, архитектурные и технические решения рождаются у самоорганизующихся команд.
- Команда должна систематически анализировать возможные способы улучшения эффективности и соответственно корректировать стиль своей работы.
5. ✅ Четыре переменных управления проектом.
- Затраты \(= const\): увеличение не поможет из-за дефицита сотрудников и извлечения пользы от них с задержкой
- Время \(= const\): непонятно, насколько увеличивать
- Качество \(= const\): снижение приведёт к появлению багов и замедлению проекта
- Объём работ \(= var\): в программных проектах, в отличие от классических, можно урезать функциональность, не потеряв ценность продукта
6. ✅ Чем user stories отличаются от технического задания?
Пользовательские истории (user stories) — способ описания требований к разрабатываемой системе, сформулированных в виде нескольких предложений на языке пользователя.
Критерии:
- Independent — Независимость историй друг от друга
- Negotiable — Обсуждаемый объём работ
- Valuable — Ценность для конечного пользователя
- Estimate — Возможность оценить трудозатраты
- Small — Краткость и лаконичность
- Testable — Возможность оценить результат
Пользовательские истории vs Техническое задание:
- Заказчику легко составить
- Легко обсуждать и уточнять
- Легко оценить
- Легко реализовать программистам
- Легко планировать и управлять
7. ✅ Итеративный и инкрементальный процесс разработки.
Инкрементальная разработка:
- Делаем фичу №1
- Делаем фичу №2
- Делаем фичу №3
Итеративная разработка:
- Делаем первую версию фичи №1
- Делаем вторую версию фичи №1
- Делаем третью версию фичи №1
Agile является и итеративным, и инкрементальным:
- Время разделяется на итерации, в конце которых продукт оказывается в готовом состоянии
- В течение каждой итерации реализуется какой-то набор пользовательских историй
7.5. ✅ Чем Agile отличается от Waterfall?
- Адаптация вместо предсказания: в Waterfall нужно заранее спланировать развитие проекта на год, а Agile не предполагает долгосрочного планирования и адаптируется к возникшим сложностям. Адаптироваться проще, чем предсказывать.
- Более ценный результат: в Waterfall не учитываются возможные изменения на рынке, а в случае Agile можно переоценить ситуацию и скорректировать курс или полностью переосмыслить продукт.
8. ✅ Что такое «простой дизайн»?
"Обычный" дизайн
- 1-я итерация ("день потерять")
Анализируем все задачи (группы задач), разрабатываем фреймворк для решения и выполняем высокоприоритетные задачи.
- 2-я итерация ("за пять минут долететь")
Опираясь на фреймворк, созданный на первой итерации, быстренько реализуем низкоприоритетные задачи.
Проблемы "обычного" дизайна:
- Анализ задачи целиком: можем переоценить или недооценить масштаб
- Состав и приоритет задач могут измениться
- Баги в API, OS, браузерах, и т.д.
Итог: задел на будущее с первой итерации оказался бесполезным или даже добавил проблем.
"Простой" дизайн — одна из трёх ключевых Agile практик, которая призвана решить обозначенные проблемы.
В "простом" дизайне мы на каждой итерации делаем только те User Stories, которые запланированы на эту итерацию, как будто следующих итераций не будет вообще. Иначе говоря, решаем задачи по мере их поступления, не забегая вперед. Код при этом должен быть минимальным, не содержать дублирования и чётко выражать мысли разработчика.
Особенности "простого" дизайна:
- Не работает в физическом мире (например, при строительстве домов)
- Работает только в Agile совместно с рефакторингом и TDD.
9. ✅ Что такое рефакторинг?
На второй итерации "простого" дизайна мы решаем задачи самым простым образом (напролом). Это приводит к таким проблемам как:
- Дублирование кода
- Длинные методы
- Большие классы (god object)
- Слишком много параметров у методов
- Слишком большая связность между классами
- Нарушение контракта базового класса
Рефакторинг — изменение структуры кода без изменения поведения программы. Позволяет избавиться от bad smells, описанных выше.
Под рефакторингом понимаются следующие небольшие изменения кода:
- Extract Interface (выделение интерфейса из класса)
- Extract Class (вынесение функциональности в отдельный класс)
- Extract Method (фрагмент метода с описательным названием)
Цикл разработки с рефакторингом:
- No bad smells
- New feature
- Bad smells (appear as a result of coding in a direct way)
- Refactor (without functional changes)
Рефакторить нужно без фанатизма, ровно до того момента, пока не вернёмся к "простому" дизайну. С каждой следующей задачей дизайн испортится и нужно будет снова рефакторить.
10. ✅ Основной цикл разработки через тестирование.
Традиционный подход к тестированию:
- Разработчики разрабатывают
- Тестировщики тестируют (вручную или автоматически)
На практике:
- Программисты не отвечают за правильность программы
- Внесение изменений в существующий код приводит к каскаду ошибок
- Появляется необходимость тестирования всей функциональности, зависимой от изменения
- Экспоненциальный рост стоимости внесения изменений
Разработка через тестирование (TDD) — один из ключевых принципов Agile, решающий обозначенные проблемы.
Принципы TDD:
- За тестирование отвечают программисты (по крайней мере на 80%)
- Для каждого куска кода, который может сломаться, есть тесты
- Сначала разрабатываются тесты, потом программы
В TDD выделяют два типа тестов:
- Модульные тесты — тестируют один метод
- Функциональные тесты — тестируют поведение подсистемы
Основной цикл TDD:
- Пишем тесты, учитывая все требования, User stories и т.д.
- Проверяем, что тесты не компилируются (необязательный шаг для новых методов/классов)
- Пишем все заглушки под классы и т.д.
- Проверяем, что ВСЕ тесты падают (обязательный шаг, мы должны проверить, что наши тесты реально проверяют то, что мы хотим, и не принимают заглушки)
- Пишем код "напролом"
- Проверяем, что тесты прошли
- Рефакторим
- Убеждаемся, что тесты по-прежнему проходят
Требования к коду:
- Выполнение всех тестов
- Простой дизайн
- Отсутствие дублирования
11. ✅ Какими преимуществами и недостатками обладает разработка через тестирование?
Преимущества TDD:
- Почти константная стоимость изменения (в отличие от экспоненциальной в случае обычной разработки)
- Вызывает привыкание (легко применять)
- Положительно влияет на дизайн
- Документирует программу (тесты могут описать поведение программы)
- Приносит моральное спокойствие
Стоит помнить, что тесты не равны верификации, то есть:
- Тесты не гарантируют правильности работы программы
- Тесты гарантируют, что программа работает так, как задумал программист (нет регрессий)
Также наличие тестов не равно TDD: в TDD тесты пишутся до написания кода, а не после. При этом можно сказать, что если нет TDD, то и тестов не будет, так как:
- Лень писать тесты после кода
- Дизайн может не позволять писать тесты
- Глупо вносить изменения в рабочий код только ради тестов
При этом если нет тестов, то нет Agile:
- Нельзя обеспечить простой дизайн
- Тяжело обеспечить отсутствие багов в конце итерации
- Тяжело рефакторить, ничего не сломав
Несмотря на то, что тесты не упоминаются ни в Scrum, ни в Kanban, их также нельзя реализовать без тестов. Владелец продукта может вносить новые user stories на любой стадии, что вызовет каскадные изменения в коде и при отсутствии тестов приведёт к багам.
Недостатки TDD:
- В TDD сложно писать тесты (однако, это почти всегда значит, что у кода плохой дизайн). Вообще говоря, если есть проблемы с TDD, значит нужно искать проблемы в коде.
- Сложно использовать с legacy-кодом. Решается написанием regression тестов на все обнаруженные баги в legacy, написанием нового кода с тестами, написанием тестов во время рефакторинга.
- Сложно обеспечить 100% покрытие тестами. В некоторых проектах требовать 100% покрытия это нормально (например в компиляторах и VCS). Но в большинстве случаев не нужно покрывать 100%. Достаточно протестировать то, что легко. Остальное протестируют тестеры.
11.5 ✅ Методология Scrum
Scrum — наиболее популярный метод управления проектами, подмножество Agile.
- Итеративный и инкрементальный проект
- Управление объёмом работ
- Описание продукта через user stories
- TDD + простой дизайн + рефакторинг
Шесть характеристик:
- Встроенная неустойчивость (нет строгого плана)
- Самоорганизующиеся проектные команды
- Перекрытие фаз разработки
- Multilearning (все участники активно учатся и изучают объектную область на протяжении всего проекта)
- Неявный контроль
- Передача знаний внутри организации
Ограничения:
- Требует чрезвычайных усилий от участников команды
- Не подходит проектам-гигантам
- Не подходит проектам, где разработка вдохновляется одним участником
Участники проектов:
- Программисты, тестеры, архитекторы, дизайнеры
- Менеджеры, связанные с проектом
- Stakeholders: топ-менеджеры, заказчики, эксперты в предметной области
12. ✅ Роли в методологии Scrum: команда.
Решает, как делать
От трёх до девяти человек. Каждый член команды работает сам по себе, но у всех общая цель и общий результат.
Обязанности команды:
- предпринимать всё возможное для достижения цели спринта;
- обеспечивать необходимый уровень качества ПО;
- самоорганизовываться;
- участвовать в выборе цели спринтов;
- демонстрировать результаты спринтов Владельцу продукта.
13. ✅ Роли в методологии Scrum: scrum-мастер.
Отвечает за соблюдение процесса.
Scrum-мастер является посредником между всеми участниками scrum'а. Он эксперт по scrum'у (следит за соблюдением правил scrum). Обычно является членом Команды (возможно, что эта должность ходит "по кругу").
Обязанности scrum-мастера:
- защищать команду от нежелательных воздействий извне;
- отвечать за преодоление организационных или коммуникационных барьеров;
- обеспечивает высокую производительность команды.
Сложная для понимания и исполнения роль.
Scrum-мастер не отвечает за успешность итераций. Если команда работала эффективно, но итерация не завершилась успешно, то это не проблема Scrum-мастера. Но если в команде ежедневные скандалы (даже при условии успешных исходов итераций), то это проблема Scrum-мастера. То есть, следим не за результатом, а за качеством процесса достижения результата.
Scrum-мастер не отвечает за успешность продукта. В провале продукта на рынке виноват Владелец продукта.
14. ✅ Роли в методологии Scrum: владелец продукта.
Решает, что делать.
Владелец продукта отвечает за успех продукта. Желательно, чтобы он разбирался в предметной области продукта. Часто является представителем заказчика.
Обязанности:
- формировать журнал продукта (список задач);
- определять приоритеты задач;
- определять даты и состав релизов;
- принимать или отклонять результаты спринтов.
Владелец продукта имеет право "последнего слова". Он может принимать продуктовое решение, даже если все остальные участники против, но несёт полную ответственность за такие решения.
15. ✅ Методология Scrum: спринты.
Спринты - итерации в стиле Agile
- Ценные для пользователя
- Инкрементальные: функциональность добавляется feature by feature
- Итеративные: уже сделанная функциональность перерабатывается и улучшается
- В конце каждого спринта продукт в рабочем состоянии
Стандартный спринт: 4 недели, но можно меньше или больше
Достаточно короткие, чтобы не было нужды в планировании
Достаточно длинные, чтобы можно было сделать что-то ценное
Состав спринта:
- Сессия планирования (выбор задач)
- Ежедневный scrum-митинг (обмен информацией)
- Демонстрационная сессия
- Ретроспективная сессия
Административные обязанности команды:
- Посещать scrum-митинг
- Поддерживать журнал спринта в адекватном состоянии
Всё остальное - чёрный ящик, не лезем в то, как команда работает
Спринт может завершиться следующим образом:
- Демонстрационная сессия (всё по плану)
- Аварийное завершение
- неправильные технические решения
- резко изменились требования к продукту
- исключено слишком много задач
- работоспособность команды заблокирована по организационным причинам
16. ✅ Методология Scrum: сессия планирования.
- Проводится в начале каждого спринта
- Занимает весь рабочий день (два блока по 4 часа)
Участники:
- Команда
- Владелец продукта
- Scrum-мастер
- Stakeholders (пассивно)
Первый сегмент сессии планирования:
- Product owner (PO) и команда выбирают задачи для спринта (набор user stories)
- Право включать или не включать задачу принадлежит PO
- Но команда может регулировать объём работ
Второй сегмент сессии планирования:
- Команда формирует Журнал спринта (по сути список TODO)
- PO участвует пассивно (отвечает на уточняющие вопросы)
17. ✅ Методология Scrum: ежедневный scrum-митинг.
- Проводится каждый день в течение спринта
- Занимает не больше 15 минут
- Цель - повышение дисциплины и фокусировки команды
Участники:
- Scrum-мастер
- Команда
- PO и stakeholders (пассивно, с разрешения scrum-мастера)
Три вопроса к каждому участнику:
- Что сделано со времени прошлого Scrum-митинга
- Что собирается сделать до следующего Scrum-митинга
- Что мешает работать максимально эффективно
18. ✅ Методология Scrum: демонстрационная сессия.
- В конце каждого спринта
- Занимает 4 часа
Участники:
- Команда
- Владелец продукта
- Scrum-мастер
- Stakeholders
Разрешено демонстрировать только готовую функциональность (потому что присутствуют люди, не участвующие в процессе разработки):
- Высокий уровень завершенности
- Всё реализовано, интегрировано, протестировано
- #NoVaporware (Sales менеджер может не понять, что это не готово, и уже завтра продать это)
После демонстрационной сессии:
- PO принимает или отклоняет результаты спринта
- Stakeholders получают возможность высказаться по поводу продукта
19. ✅ Методология Scrum: ретроспективная сессия.
- Факультативная сессия по результатам спринта
Участники:
Вопросы:
- Что удалось в течение спринта?
- Что не удалось в течение спринта?
- Как можно улучшить нашу работу?
20. ✅ Методология Scrum: чем журнал продукта отличается от журнала спринта?
Журнал продукта (product backlog) — список user stories с расставленными приоритетами. Наиболее приоритетные истории могут быть детализированы.
Журнал спринта (sprint backlog) — список технических задач на текущий спринт. Задачи небольшие - выполняются не более чем за два дня (если задача больше - декомпозируем).
21. ✅ Методология Scrum: график спринта.
Размещается на видном месте, чтобы команда всегда его видела.
По оси Y - оставшийся объём работ, по оси X - время.
Рисуем идеальную прямую - в которой в последний день объём работ = 0, и затем каждый день отмечаем точку - сколько ещё не сделано. Таким образом если наш спринт идёт хорошо - наш график похож на идеальную прямую.
Если не успеваем что-то сделать, то выкидываем из спринта и переносим на следующий. Это позволяет не увеличить затраты и не ухудшить качество.

22. ✅ Вспомогательные практики: 40-часовая рабочая неделя.
Вкратце: программисты не работают больше 40 часов в неделю. Вообще.
Мотивация:
Стандартный программист стремится первые 80% времени работать на расслабоне. Из-за этого на последних 20% начинается аврал. Аврал - это плохо: из-за повышенной нагрузки ухудшается качество кода, производительность падает, возникают конфликты (кто-то не может работать дольше, и на него все злятся).
Практика:
Авралы запрещаются, и программистам запрещается работать больше 40 часов в неделю (или сколько полагается по трудовому законодательству страны) независимо от фазы проекта. Таким образом, сами программисты не беспокоятся о том, что через полгода придётся кранчить, а проджект овнер и скрам мастер мотивированы организовывать работу сразу правильно, потому что переработка в конце не спасёт.
Естественно, недопустимо от этого правила отказываться. Если "на берегу" договорились, что авралов не будет, но в конце проекта они таки случились, это нехорошо.
23. ✅ Вспомогательные практики: стандарты кодирования.
Вкратце: все пишут код по одному стандарту, есть code style, best practices, комментарии.
Практика:
Код читают намного чаще, чем пишут - когда ищут баги, когда добавляют фичи, когда его копируют в другое место. Поэтому очень полезно иметь стандарты кодирования, чтобы во всём проекте код был одинаковый и его было легко читать. Стандарты могут быть хоть какие, главное - одинаковые везде (внутри одной системы. Стандарт может быть разным для базы данных и фронтенда, например). Помимо самого удобства существования стандартов, они практически необходимы для следующих двух практик.
24. ✅ Вспомогательные практики: коллективное владение кодом.
Вкратце: всю кодовую базу могут читать и улучшать все члены проекта.
Мотивация:
Если в каком-то модуле работает только один человек (Иванов), он может в нём творить что угодно для своего удобства. И если Иванов занят/заболел/уволился (bus factor), а этот код надо поддерживать, то это будет больно - даже если Иванов писал код нормально, остальным придётся с нуля вникать.
Практика:
Любой код может читать и улучшать (делать туда pull request) любой член команды. За счёт этого, если Иванов недоступен, код может поправить Петров, который его читал и делал поправки, то есть как-то разбирается. Понятно, что без стандартов кодирования разбираться в чужом коде намного сложнее.
25. ✅ Вспомогательные практики: парное программирование.
Вкратце: особо важное пишут два программиста за одним компьютером.
Практика:
Если есть два программиста одна клавиатура, то один ("ведущий", driver) пишет, а другой ("штурман", observer) думает над задачей и смотрит, как первый пишет. И они периодически меняются. Как олимпиадники на ICPC.
За счёт того, что "штурман" прямо смотрит на выдаваемый код, он может сразу замечать ошибки, который пишущий не видит. Заодно он не так сфокусирован на собственно коде и может предлагать решения.
При правильной организации при этом методе получается прирост качества, оправдывающий двойную трату времени программистов. Поэтому используется для особо важного кода, формочки клепать и поодиночке можно. Также при парном программировании хорошо идёт передача знаний.
Однако, эта практика зачастую саботируется самими программистами. Кто-то просто предпочитает работать соло, особенно опытные программисты, кто-то не хочет перенапрягаться, потому что расслабиться как наедине не получится. Или может получиться, что пара программистов заболтается и производительность упадёт.