оценку можно дать только качественную, но не количественную. Использование
больших строительных блоков, таких как STL в C++ или ассоциативные массивы и
обработка строк в скриптовых языках, приводит к более компактному коду и серьезно
сокращает время на создание приложения. Как мы уже отмечали, за удобство
приходится платить, хотя проблемы с быстродействием не имеют большого
значения для программ типа рассмотренной, поскольку выполняется она всего
несколько секунд.
Менее понятно, однако, как оценить ослабление контроля над программой и
понимания происходящего со стороны программиста, когда размер
"заимствованного" кода становится настолько большим, что отследить все нюансы
становится невозможно. STL-версия — это как раз тот самый случай: ее
производительность непредсказуема, и
нет простых способов как-то с этим
разобраться. Немногие из нас обладают достаточным запасом сил и энергии, чтобы
разыскать источник трудностей и исправить ошибки.
Это всеобщая и все растущая проблема программного обеспечения — по мере того
как библиотеки, интерфейсы и инструменты все более усложняются, они становятся
все менее понятными и менее
управляемыми. Когда все работает, среда
программирования, имеющая много вспомогательных средств, может быть весьма
продуктивна, но когда эти средства отказывают, трудно найти спасение.
Действительно, если проблемы связаны с быстродействием или с трудноуловимыми
логическими ошибками, то мы можем даже не понять, что что-то идет не так, как
надо.
Проектирование и реализация этой
программы дали нам несколько уроков, которые
стоит усвоить перед тем, как браться за большие программы. Первый — это
важность выбора простых алгоритмов и структур данных: самых простых из всех, что
смогут выполнить задачу, уложившись во все ограничения (по времени, размеру и т.
п.). Если кто-то уже описал эти структуры или
алгоритмы и создал библиотеку, то
нам это только на руку; наша C++ версия выигрывала как раз за счет этого.
Следуя совету Брукса, мы считаем, что лучше всего начинать детальное
проектирование со структур данных, руководствуясь знаниями о том, какие
алгоритмы могут быть использованы; после того как структуры данных определены,
код проектируется и пишется
гораздо проще.
Трудно сначала спроектировать программу целиком, а потом уже писать; создание
реальных программ всегда включает в себя повторения и эксперименты. Процесс
непосредственного написания программы вынуждает программиста уточнять
решения, которые до этого существовали лишь в общем виде. Для нашей
программы это весьма актуально — она претерпела множество изменений в
деталях. Изо
всех сил старайтесь начинать с чего-нибудь простого, внося
улучшения, диктуемые опытом. Если бы нашей целью было просто реализовать
алгоритм цепей Маркова для развлечения — тексты бывают довольно забавными, —
мы практически наверняка написали бы его на Awk или Perl, причем даже не
позаботившись навести глянец, который мы вам продемонстрировали, — и на этом
успокоились бы
.
Однако код для настоящего промышленного приложения требует го-'j раздо больших
затрат, чем код прототипа. Если к представленным здесь программам относиться как
к промышленной реализации (поскольку они были отлажены и тщательно
оттестированы), то усилия на создание промышленной версии будут на один-два
порядка больше, чем при написании программы для собственного использования.