убедиться в том, что все ваши тесты корректны. Вы также должны проверить весь дизайн системы – возможно, он требует серьезного пересмотра.
Однако существует опасность. Плохо организованное тестирование – это все равно, что розовые очки, сквозь которые вы смотрите на свою систему. Вы получаете ложную уверенность в том, что ваша система в порядке, – еще бы, ведь все тесты срабатывают. Вы продолжаете движение вперед, не подозревая, что оставляете позади себя ловушку. Как только вы в следующий раз пойдете этим же путем, ловушка может сработать.
Весь трюк, связанный с тестированием, заключается в нахождении приемлемого для вас уровня дефектов. Если вы в состоянии позволить себе одну жалобу со стороны заказчика в течение месяца, вкладывайте ресурсы в улучшение тестирования и улучшайте его до тех пор, пока не достигнете желаемого уровня. Затем, используя полученный стандарт тестирования, продолжайте движение вперед, так как состояние системы считается отличным в случае, если все тесты срабатывают.
Заглядывая вперед, отмечу, что в дальнейшем разговор пойдет о двух наборах тестов. Тесты модулей (unit tests) разрабатываются программистами для того, чтобы убедиться в корректной работе разрабатываемого ими кода. Функциональные тесты (functional tests) разрабатываются (или по крайней мере специфицируются) заказчиками для того, чтобы убедиться в том, что система как единое целое работает именно так, как она должна работать.
Таким образом, для тестов существуют две аудиенции. Программисты должны оформить свою уверенность в разрабатываемом коде в реальную форму для того, чтобы кто-то другой также мог получить эту уверенность. Заказчики должны подготовить набор тестов для того, чтобы получить от системы подтверждение своей уверенности: Замечательно, я полагаю, что если вы сможете добиться срабатывания всех этих тестов, это значит, что система работает.
Программисты ничего не знают. Говоря точнее, программисты не знают ничего такого, что является интересным для бизнесменов. Если бы бизнесмены могли обойтись без программистов, они бы вышвырнули нас вон в одну секунду.
К чему я веду? Если вы решили тестировать, вы должны получить откуда-либо ожидаемые ответы. Так как вы (программист) ничего не знаете, вы должны спросить у кого-то еще. Они сообщат вам, какие ответы являются ожидаемыми и какие случаи являются необычными с точки зрения бизнеса.
Если вы намерены задать вопрос, вы должны быть готовыми услышать ответ. Таким образом, слушание – это третий род деятельности в рамках разработки программного обеспечения.
Программисты должны слушать с большим вниманием. Они должны услышать от заказчика суть бизнес-проблемы. Они должны помочь заказчику понять, что является простым, а что – сложным, это можно считать активной формой слушания. Обратная связь от программистов к заказчику помогает заказчику самому лучше понять суть стоящей перед ним проблемы.
Если вы просто скажете участникам проекта: Вы должны слушать друг друга, и вы должны слушать заказчика, то этим вы не добьетесь желаемого результата. Многие уже попробовали это и пришли к выводу, что подобные простые директивы не срабатывают. Мы должны найти способ структурировать коммуникацию так, чтобы в результате обсуждения речь шла именно о тех вещах, которые нуждаются в обсуждении, это должно происходить именно в то время, когда возникает надобность в подобном обсуждении, и именно в том объеме, в котором эти вещи должны обсуждаться. Кроме того, разрабатываемые нами правила должны избавлять команду от коммуникации, которая только мешает дальнейшему развитию проекта.
Почему нельзя просто слушать, затем писать тестовый случай, затем заставить его работать, затем опять слушать, опять писать тестовый случай и опять заставить его работать, и так далее? Потому что мы знаем, что это не сработает. Конечно, вы можете попробовать действовать именно так в течение некоторого времени. Вы можете даже действовать так в течение достаточно длительного времени. Однако в определенный момент вы не сможете продолжать работать над проектом. Вы попадете в ситуацию, когда для того, чтобы заставить работать некоторый тестовый случай, вам придется нарушить работу другого тестового случая. Или для того, чтобы заставить работать тестовый случай, вам придется затратить столько усилий, что это перестанет быть экономически выгодным. Энтропия проглатывает еще одну жертву.
Единственным способом избежать этого является проектирование. Проектирование – это создание структуры, которая организует логику в системе. Хороший дизайн организует логику так, что для внесения измене ний в одну часть системы вам не нужно обязательно вносить изменения в другую часть системы. Хороший дизайн предусматривает, что каждый логический раздел системы оформляется в виде самостоятельного независимого фрагмента программы. Хороший дизайн размещает логику рядом с данными, в отношении которых она действует. Хороший дизайн позволяет расширять систему, модифицируя только лишь одно ее место.
Плохой дизайн – это прямая противоположность. Если в рамках плохого дизайна вы пытаетесь внести в систему концептуальное изменение, вам приходится вносить изменения сразу в несколько разных мест системы. В рамках плохого дизайна одна и та же логика дублируется в нескольких местах. Со временем затраты, вызванные плохим дизайном, становятся чрезмерно большими. Вы просто забываете о том, в какие места системы необходимо внести все связанные между собой изменения. Вы не можете добавить в систему новую функцию, не нарушив при этом работу одной из уже существующих функций.
Сложность – это еще одна причина плохого дизайна. Если для того, чтобы выяснить, что же все- таки происходит, дизайн предусматривает четыре уровня перенаправления и если эти уровни не обладают функциональным или смысловым предназначением, значит, дизайн плохой.
Таким образом, последним родом деятельности, который мы должны структурировать в рамках разрабатываемой нами новой дисциплины, – это проектирование, или, по-другому, формирование дизайна. Мы должны сформировать контекст, в рамках которого создается только хороший дизайн, а плохой дизайн исправляется. Кроме того, в рамках этого контекста о текущем дизайне системы знает каждый, кому это необходимо.
Как будет показано в последующих главах, методы формирования дизайна в ХР существенно отличаются от методов, традиционно используемых в рамках многих других дисциплин разработки программного обеспечения. В рамках ХР проектирование является частью ежедневной работы каждого из программистов. Программисты ХР занимаются проектированием прямо в процессе кодирования. Однако вне зависимости от стратегии, которая используется для получения хорошего дизайна, в процессе разработки программного продукта проектирование не выполняется по желанию. Это неотъемлемая часть любого программного проекта, и для того, чтобы сделать разработку программы эффективной, вы должны уделить проектированию очень серьезное внимание.
Итак, вы кодируете потому, что без этого вы вообще не сможете получить какого-либо результата. Вы тестируете потому, что без этого вы не сможете определить, завершена ли ваша работа. Вы слушаете потому, что без этого вы не сможете понять, что собственно кодировать и что тестировать. Наконец, вы проектируете для того, чтобы получить возможность продолжать кодировать, тестировать и слушать неограниченное время. Вот и все. Именно эти четыре рода деятельности нам и предстоит структурировать в рамках нашей новой дисциплины:
• кодирование;
• тестирование;
• слушание;
• проектирование.
Часть 2.
Решение