Страница 5 из 20
Рис. 1.6. Время на выполнение итерации с использованием и без использования методики TDD
хорошо известную методику разработки через тестирование (Test-Driven Development; TDD). В остальные дни он писал код, не ограничивая себя рамками этой методики.
Прежде всего обратите внимание на кривую обучения, заметную на рис. 1.6. Каждый раз на решение задачи затрачивалось меньше времени. Отметьте также, что в дни, когда применялась методика TDD, упражнение выполнялось примерно на 10 % быстрее, чем в дни без применения TDD, и что даже худший результат, полученный с TDD, оказался лучше самого лучшего результата, полученного без TDD.
Кто-то, взглянув на этот результат, может посчитать его удивительным. Но для тех, кто не поддался обману самонадеянности Зайца, результат будет вполне ожидаемым, потому что они знают простую истину разработки программного обеспечения:
Поспешай не торопясь.
И она же является ответом на дилемму, стоящую перед руководством. Единственный способ обратить вспять снижение продуктивности и увеличение стоимости – заставить разработчиков перестать думать как самонадеянный Заяц и начать нести ответственность за беспорядок, который они учинили.
Разработчики могут подумать, что проблему можно исправить, только начав все с самого начала и перепроектировав всю систему целиком, – но это в них говорит все тот же Заяц. Та же самонадеянность, которая прежде уже привела к беспорядку, теперь снова говорит им, что они смогут построить лучшую систему, если только вновь вступят в гонку. Однако в действительности все не так радужно:
Самонадеянность, управляющая перепроектированием, приведет к тому же беспорядку, что и прежде.
Заключение
Любой организации, занимающейся разработкой, лучше всего избегать самонадеянных решений и с самого начала со всей серьезностью отнестись к качеству архитектуры ее продукта.
Серьезное отношение к архитектуре программного обеспечения подразумевает знание о том, что такое хорошая архитектура. Чтобы создать систему, дизайн и архитектура которой способствуют уменьшению трудозатрат и увеличению продуктивности, нужно знать, какие элементы архитектуры ведут к этому.
Именно об этом рассказывается в данной книге. В ней рассказывается, как выглядит добротная, чистая архитектура и дизайн, чтобы разработчики могли создавать системы, способные приносить прибыль долгое время.
2. История о двух ценностях
Всякая программная система имеет две разные ценности: поведение и структуру. Разработчики отвечают за высокий уровень обеих этих ценностей. Но, к сожалению, они часто сосредоточиваются на чем-то одном, забывая про другое. Хуже того, они нередко сосредоточиваются на меньшей из двух ценностей, что в конечном итоге обесценивает систему.
Поведение
Первая ценность программного обеспечения – его поведение. Программистов нанимают на работу, чтобы они заставили компьютеры экономить деньги или приносить прибыль заинтересованной стороне. Для этого мы помогаем заинтересованным сторонам разработать функциональную спецификацию или документ с требованиями. Затем пишем код, заставляющий компьютеры заинтересованных сторон удовлетворять этим требованиям.
Когда компьютер нарушает требования, программисты вынимают свои отладчики и исправляют проблему.
Многие программисты полагают, что этим их работа ограничивается. Они уверены, что их задача – заставлять компьютеры соответствовать требованиям и исправлять ошибки. Они жестоко ошибаются.
Архитектура
Вторая ценность программного обеспечения заключена в самом названии «программное обеспечение». Слово «обеспечение» означает «продукт»; а слово «программное»… Как раз в нем и заключается вторая ценность.
Идея программного обеспечения состоит в том, чтобы дать простую возможность изменять поведение компьютеров. Поведение компьютеров в некоторых пределах можно также изменять посредством аппаратного обеспечения, но этот путь намного сложнее.
Для достижения этой цели программное обеспечение должно быть податливым – то есть должна быть возможность легко изменить его. Когда заинтересованные стороны меняют свое мнение о некоторой особенности, приведение ее в соответствие с пожеланиями заинтересованной стороны должно быть простой задачей. Сложность в таких случаях должна быть пропорциональна лишь масштабу изменения, но никак не его форме.
Именно эта разница между масштабом и формой часто является причиной роста стоимости разработки программного обеспечения. Именно по этой причине стоимость растет пропорционально объему требуемых изменений. Именно поэтому стоимость разработки в первый год существенно ниже, чем во второй, а во второй год ниже, чем в третий.
С точки зрения заинтересованных сторон они просто формируют поток изменений примерно одинакового масштаба. С точки зрения разработчиков, заинтересованные стороны формируют поток фрагментов, которые они должны встраивать в мозаику со все возрастающей сложностью. Каждый новый запрос сложнее предыдущего, потому что форма системы не соответствует форме запроса.
Я использовал здесь слово «форма» не в традиционном его понимании, но, как мне кажется, такая метафора вполне уместна. У разработчиков программного обеспечения часто складывается ощущение, что их заставляют затыкать круглые отверстия квадратными пробками.
Проблема, конечно же, кроется в архитектуре системы. Чем чаще архитектура отдает предпочтение какой-то одной форме, тем выше вероятность, что встраивание новых особенностей в эту структуру будет даваться все сложнее и сложнее. Поэтому архитектуры должны быть максимально независимыми от формы.
Наибольшая ценность
Функциональность или архитектура? Что более ценно? Что важнее – правильная работа системы или простота ее изменения?
Если задать этот вопрос руководителю предприятия, он наверняка ответит, что важнее правильная работа. Разработчики часто соглашаются с этим мнением. Но оно ошибочно. Я могу доказать ошибочность этого взгляда простым логическим инструментом исследования экстремумов.
Если правильно работающая программа не допускает возможности ее изменения, она перестанет работать правильно, когда изменятся требования, и вы не сможете заставить ее работать правильно. То есть программа станет бесполезной.
Если программа работает неправильно, но легко поддается изменению, вы сможете заставить работать ее правильно и поддерживать ее работоспособность по мере изменения требований. То есть программа постоянно будет оставаться полезной.
Эти аргументы могут показаться вам неубедительными. В конце концов, нет таких программ, которые нельзя изменить. Однако есть системы, изменить которые практически невозможно, потому что стоимость изменений превысит получаемые выгоды. Многие системы достигают такого состояния в некоторых своих особенностях или конфигурациях.
Если спросить руководителя, хотел бы он иметь возможность вносить изменения, он ответит, что безусловно хотел бы, но тут же может уточнить, что работоспособность в данный момент для него важнее гибкости в будущем. Однако если руководитель потребует внести изменения, а ваши затраты на эти изменения окажутся несоизмеримо высокими, он почти наверняка будет негодовать оттого, что вы довели систему до такого состояния, когда стоимость изменений превышает разумные пределы.
Матрица Эйзенхауэра
Рассмотрим матрицу президента Дуайта Дэвида Эйзенхауэра для определения приоритета между важностью и срочностью (рис. 2.1). Об этой матрице Эйзенхауэр говорил так: