Экстремальное программирование

Экстремальное программирование. Разработка.
Конспект лекций для 14-й Лесной Школы. 
Подготовлен специалистами ДИМАС, Хабаровск.

  • Выбирайте самое простое решение 
"Усложнять - просто, упрощать - сложно" Народная мудрость

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

Рефакторите чужой код, если он кажется вам сложным. Если что-то выглядит сложным - это верный признак проблемы в коде.

Сохраняйте решения насколько возможно простыми как можно дольше. Никогда не добавляйте функциональность на будущее - до того, как появляется в ней необходимость. Однако имейте в виду: сохранять дизайн простым - тяжелая работа. 

  • Рефакторитнг (Переработка кода) 
Мы, программисты, склонны держаться за свои программы до последнего, даже после того, как они становится неуклюжими. Мы продолжаем повторно использовать неудобный в сопровождении код, поскольку он все еще как-то работает и мы боимся испортить его. Но действительно ли это выгодно? XP считает, что это невыгодно. Когда мы убираем избыточность, улучшаем устаревший дизайн, убираем неиспользуемые куски - мы делаем рефакторинг. Рефакторинг в конечном итоге экономит время и улучшает качество продукта.

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


  • Вам это не понадобится 
Воздержитесь от заполнения системы вещами, которые понадобятся вам в будущем. Только 10% от ожидаемого действительно понадобится вам в первоначальном виде, то есть 90% вашего времени будет потрачено впустую.

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

  • Unit Test-ы 

Unit тесты играют ключевую роль в XP. Они позволяют быстро менять код, не боясь наделать новых ошибок. Unit тест пишется для каждого класса, тест должен проверять все аспекты работы класса - тестировать все, что может не работать.

Хитростью здесь является то, что тест для класса должен быть написан раньше самого класса. Это значит, что как только вы выпустите первый работающий результат, он будет поддерживаться системой тестирования. Для проведения тестов пишется специальная система тестирования со своим интерфейсом.

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

Огромным искушением является сэкономить на Unit тестах, когда мало времени. Но этим Вы только обманываете себя. Чем сложнее написать тест, тем больше времени он потом сэкономит. Это доказано практикой.

Unit тесты позволяют осуществить коллективное владение кодом. Они позволяют относительно легко пересматривать плохой код. Также Unit тесты позволяют в любой момент иметь стабильно работающую систему. 

  • Приемочные тесты 

Приемочные тесты (ранее их также называли Функциональные) пишутся на основе карточек. Они рассматривают и проверяют систему целиком. Составляются они не программистом, а Заказчикам. Если все тесты по данной карточке проходят, значит все работы по ней завершены, и можно сдавать работу Заказчику.

Приемочные тесты автоматизируются так, чтобы имелась возможность их часто запускать.

  • Когда обнаружена ошибка 

Если обнаруживается ошибка, то создается тест, чтобы предотвратить ее повторное появление. Ошибка, произошедшая в рабочей системе (уже установленной), требует написания функционального теста. Создание функционального теста непосредственно перед диагностикой ошибки позволяет заказчикам четко описать проблему и довести эту проблему до разработчиков.

Невыполнившийся функциональный тест требует создания Unit теста. Это помогает сфокусировать усилия по отладке и четко показывает, когда ошибка исправлена.

  • Парное программирование 

Весь код системы (за исключением пробных решений) пишется парами. Два разработчика сидят рядом за одним компьютером. Один набирает, другой смотрит. Время от времени они меняются. В одиночку работать не разрешается. Звучит необычно. Но XP утверждает, что после небольшого периода адаптации большинство людей прекрасно работают в парах. Им даже нравится, поскольку работа делается заметно быстрее. Действует принцип "Одна голова хорошо, а две лучше". Пары обычно находят более оптимальные решения. Кроме того, существенно увеличивается качество кода, снижается число ошибок и ускоряется обмен знаниями между разработчиками.

  • Коллективное владение кодом 

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

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

  • Частая интеграция 

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

Каждая пара разработчиков должна отдавать свой код, как только для этого появляется разумная возможность. Это может быть момент, когда все UnitTest-ы проходят на 100%. Отдавая изменения несколько раз в день, Вы сводите проблемы интеграции практически к нулю. Интегрируя изменения ежедневно маленькими порциями вы не окажетесь перед необходимостью тратить неделю, чтобы связать систему в одно целое непосредственно перед сдачей проекта. Всегда работайте над последней версией системы.

Для менеджера. Если разработчик не отдает изменений дольше одного дня - это ясный индикатор серьезной проблемы. Вы должны немедленно разобраться, в чем дело. Весь опыт XP команд говорит что всегда причиной задержки является плохой дизайн и его всегда потом приходится переделывать.

  • Соглашение о кодировании 

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

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

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

  • Меняйтесь задачами 

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

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

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

При начале новой итерации каждый разработчик должен перейти на новую задачу. Парное программирование помогает преодолеть проблему адаптации (это значит, что новый разработчик может начать работать в паре с опытным в данной области разработчиком).

Такая практика также стимулирует появление новых идей и улучшение кода.

  • Заказчик в команде 

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

  • Оставляйте оптимизацию на потом 

Никогда не оптимизируйте ничего до окончания кодирования. Никогда не пытайтесь угадать, где будут узкие места по производительности.

Сделайте чтобы программа заработала, затем - чтобы работала правильно, затем - чтобы работала быстро.

  • Не работайте сверх графика 

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

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

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


  • Unit Test-ы 

Unit тесты играют ключевую роль в XP. Они позволяют быстро менять код, не боясь наделать новых ошибок. Unit тест пишется для каждого класса, тест должен проверять все аспекты работы класса - тестировать все, что может не работать.

Хитростью здесь является то, что тест для класса должен быть написан раньше самого класса. Это значит, что как только вы выпустите первый работающий результат, он будет поддерживаться системой тестирования. Для проведения тестов пишется специальная система тестирования со своим интерфейсом.

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

Огромным искушением является сэкономить на Unit тестах, когда мало времени. Но этим Вы только обманываете себя. Чем сложнее написать тест, тем больше времени он потом сэкономит. Это доказано практикой.

Unit тесты позволяют осуществить коллективное владение кодом. Они позволяют относительно легко пересматривать плохой код. Также Unit тесты позволяют в любой момент иметь стабильно работающую систему. 

  • Приемочные тесты 

Приемочные тесты (ранее их также называли Функциональные) пишутся на основе карточек. Они рассматривают и проверяют систему целиком. Составляются они не программистом, а Заказчикам. Если все тесты по данной карточке проходят, значит все работы по ней завершены, и можно сдавать работу Заказчику.

Приемочные тесты автоматизируются так, чтобы имелась возможность их часто запускать.

  • Когда обнаружена ошибка 

Если обнаруживается ошибка, то создается тест, чтобы предотвратить ее повторное появление. Ошибка, произошедшая в рабочей системе (уже установленной), требует написания функционального теста. Создание функционального теста непосредственно перед диагностикой ошибки позволяет заказчикам четко описать проблему и довести эту проблему до разработчиков.

Невыполнившийся функциональный тест требует создания Unit теста. Это помогает сфокусировать усилия по отладке и четко показывает, когда ошибка исправлена.

  • Парное программирование 

Весь код системы (за исключением пробных решений) пишется парами. Два разработчика сидят рядом за одним компьютером. Один набирает, другой смотрит. Время от времени они меняются. В одиночку работать не разрешается. Звучит необычно. Но XP утверждает, что после небольшого периода адаптации большинство людей прекрасно работают в парах. Им даже нравится, поскольку работа делается заметно быстрее. Действует принцип "Одна голова хорошо, а две лучше". Пары обычно находят более оптимальные решения. Кроме того, существенно увеличивается качество кода, снижается число ошибок и ускоряется обмен знаниями между разработчиками.

  • Коллективное владение кодом 

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

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

  • Частая интеграция 

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

Каждая пара разработчиков должна отдавать свой код, как только для этого появляется разумная возможность. Это может быть момент, когда все UnitTest-ы проходят на 100%. Отдавая изменения несколько раз в день, Вы сводите проблемы интеграции практически к нулю. Интегрируя изменения ежедневно маленькими порциями вы не окажетесь перед необходимостью тратить неделю, чтобы связать систему в одно целое непосредственно перед сдачей проекта. Всегда работайте над последней версией системы.

Для менеджера. Если разработчик не отдает изменений дольше одного дня - это ясный индикатор серьезной проблемы. Вы должны немедленно разобраться, в чем дело. Весь опыт XP команд говорит что всегда причиной задержки является плохой дизайн и его всегда потом приходится переделывать.

  • Соглашение о кодировании 

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

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

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

  • Меняйтесь задачами 

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

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

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

При начале новой итерации каждый разработчик должен перейти на новую задачу. Парное программирование помогает преодолеть проблему адаптации (это значит, что новый разработчик может начать работать в паре с опытным в данной области разработчиком).

Такая практика также стимулирует появление новых идей и улучшение кода.

  • Заказчик в команде 

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

  • Оставляйте оптимизацию на потом 

Никогда не оптимизируйте ничего до окончания кодирования. Никогда не пытайтесь угадать, где будут узкие места по производительности.

Сделайте чтобы программа заработала, затем - чтобы работала правильно, затем - чтобы работала быстро.

  • Не работайте сверх графика 

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

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