Мы рассмотрели несколько различных грамматик – от простых строчно-ориентированных форматов до более сложных, которые выглядят как реальные языки. Если для реализации требуются дополнительные усилия, тогда зачем выбирать более сложную грамматику?
Компромиссом являются расширяемость и сопровождение. В то время как программа грамматического разбора «реального» языка может быть более сложной в написании, для пользователя она будет намного понятнее, и ее будет легче расширить за счет добавления новых средств и функциональных возможностей. Слишком простые языки могут быть легкими для грамматического разбора, но они могут быть зашифрованными – подобно примеру с программой sendmail (см. «Языки управления данными и процедурные языки»).
Учитывая, что срок службы большинства прикладных программ превышает ожидаемый, вам лучше примириться с суровой действительностью и принять заранее более сложный и удобочитаемый язык. Усилия, затраченные вначале, многократно окупятся за счет снижения затрат на поддержку и сопровождение.
• Метапрограммирование
• Можно ли выразить некоторые из требований проекта, над которым вы работаете в настоящее время, на языке, отражающем специфику предметной области? Возможно ли написать компилятор или транслятор, который мог бы сгенерировать большую часть требуемой программы?
• Если вы решили принять мини-язык как способ программирования, близкий к предметной области, вы принимаете и то, что для их реализации потребуются некоторые усилия. Как выдумаете, есть ли способы, при которых «скелет», разработанный для одного проекта, может многократно использоваться в других?
5. Требуется реализовать мини-язык управления простым графическим пакетом (возможно, с графикой в относительных командах). Язык состоит из однобуквенных команд. После некоторых команд указывается число. Например, следующий фрагмент изображает на экране прямоугольник. (Ответ см. в Приложении В.)
Р 2 # select pen 2
D # pen down
W 2 # draw west 2cm
N 1 # then north 1
E 2 # then east 2
S 1 # then back south
U # pen up
Составьте программу, которая анализирует этот язык. Она должна быть разработана так, чтобы операция добавления новых команд была несложной.
6. Спроектируйте грамматику BNF (нормальной формы Бэкуса-Наура), чтобы провести грамматический разбор спецификаций времени. Все указанные примеры должны быть успешно проанализированы. (Ответ см. в Приложении В.)
4pm, 7:38pm, 23:42, 3:16, 3:16am
7. Реализуйте программу грамматического разбора для грамматики нормальной формы Бэкуса-Наура в упражнении 6, используя программы уасс, bison или аналогичный генератор грамматического разбора. (Ответ см. в Приложении В.)
8. Реализуйте программу грамматического разбора времени, используя Perl. (Подсказка: регулярные выражения позволяют написать хорошие программы грамматического разбора.) (Ответ см. в Приложении В.)
13Оценка
Сколько времени потребуется для пересылки «Войны и мира» по модемной линии в 56 байт? Какое место займет на диске миллион имен и адресов? Сколько времени понадобится для прохождения 1000-байтового блока через маршрутизатор? Сколько месяцев потребуется, чтобы завершить ваш проект?
С одной стороны, все эти вопросы бессмысленны – информация, содержащаяся в них, недостаточна для ответа. И тем не менее, на все из них можно ответить, если вы сможете провести оценку. В процессе работы над генерацией оценки, вы придете к большему пониманию мира, в котором обитают ваши программы.
Научившись оценивать и развивая этот навык до уровня, на котором у вас появляется интуитивное ощущение величины того или иного предмета, вы сможете показать явно магическую способность к определению их выполнимости. Если кто-либо говорит: «Мы вышлем вам резервную копию по каналу ISDN в центральный офис», вы сможете интуитивно осознать, имеет ли это смысл. Когда вы составляете программу, вы сможете понять, какие подсистемы нуждаются в оптимизации, а какие нужно оставить в покое.
Подсказка 18: Проводите оценки во избежание сюрпризов
В конце данного раздела мы приведем единственно правильный ответ (в виде бесплатного приложения), который необходимо давать во всех случаях, когда вас просят оценить что-либо.
Насколько точной является «приемлемая точность»?
До некоторой степени все ответы представляют собой оценки. Просто некоторые из них точнее остальных. Так что первым вопросом, который вам придется задать самому себе, когда кто-либо просит вас об оценке, является вопрос о контексте, в котором будет приниматься данный вами ответ. Нужна ли здесь высокая точность, или речь идет о примерной цифре?
• Если ваша бабушка спрашивает, когда вы появитесь, она, вероятно, задается вопросом, готовить вам обед или ужин. С другой стороны, водолаз, оказавшийся в подводной ловушке и испытывающий недостаток воздуха, интересуется ответом с точностью до секунды.
• Каково значение числа «пи»? Если вас интересует, какое количество бордюрного камня понадобится для оформления цветочной клумбы, то цифра 3 вероятно будет приемлемой [15]. На школьном уровне хорошим приближением является 22/7. Ну а если вы работаете в NASA, то двенадцати цифр после запятой будет вполне достаточно.
Одной из интересных особенностей оценки является тот факт, что интерпретация ее результата зависит от используемых вами единиц измерения. Если выговорите, что для некоего действия потребуется 130 рабочих дней, то люди будут ожидать наступления этого события в достаточно узком интервале. Но если вы скажете «около шести месяцев», они будут знать, что этого события следует ожидать через 5–7 месяцев. Обе цифры обозначают одну и ту же продолжительность, но «130 дней», вероятно, подразумевает большую точность, чем вы полагаете. Мы рекомендуем следующую градацию оценок времени:
Продолжительность == Оценка (порядок)
1-15 дней == дни
3-8 недель == недели
8-30 недель == месяцы
30 и более недель == перед тем, как оценить, стоит хорошенько подумать
Так, если после всей необходимой работы, вы придете к решению, что проект займет 125 рабочих дней (25 недель), он может быть оценен как «примерно за шесть месяцев».
Те же принципы применимы к оценкам любых количеств: выберите единицы, в которых будет дан ответ, чтобы отразить точность, которую вы намерены передать.
Из чего исходят оценки?
Все оценки основаны на моделях проблемы. Но перед тем как углубиться в методики построения моделей, необходимо упомянуть о главной хитрости, которая всегда дает хорошие результаты: спросите того, кто уже делал это. Перед тем как вплотную заняться построением модели, оглянитесь вокруг в поисках тех, кто ранее находился в подобной ситуации. Посмотрите, как они решали свою задачу. Маловероятно, что вы обнаружите точное совпадение, но будете удивлены, сколь часто вы успешно обращались к опыту других.
Понимание сути заданного вопроса
Первой частью любого упражнения в составлении оценки является понимание сути заданного вопроса. Как и в случае с вопросами точности, обсуждаемыми выше, вам необходимо осознать масштаб предметной области. Зачастую он неявно выражен в самом вопросе, но осознание масштаба, перед тем как начать строить предположения, должно войти у вас в привычку. Зачастую выбранная вами предметная область частично формирует ответ, который вы даете: «Если предположить, что по дороге не будет аварий и машина заправлена, я буду там через 20 минут».
Построение модели системы
Эта часть процесса оценки – самая интересная. Исходя из вашего понимания заданного вопроса, постройте в уме скелет действующей модели. Если вы оцениваете время отклика, то в вашей модели может иметься узел обслуживания и некий входной поток. При работе над проектом моделью могут послужить стадии, которые ваша организация использует в разработке, наряду с весьма грубым представлением того, как система может быть реализована.
Построение модели может быть творческим процессом, полезным в долгосрочной перспективе. Зачастую построение модели приводит к открытию схем и процессов, лежащих в основе чего-либо и не видимых невооруженным глазом. У вас даже может возникнуть желание повторно исследовать исходный вопрос: «Вы попросили дать оценку X. Однако, похоже, что У, являющийся вариантом X, может быть выполнен примерно в два раза быстрее, и при этом вы теряете лишь одну характеристику».
Построение модели вносит погрешности в процесс оценки. Это и неизбежно, и полезно. Вы жертвуете простотой модели ради точности. Удвоение усилий, прилагаемых к модели, может увеличить точность лишь незначительно. Ваш опыт подскажет вам, когда закончить процесс совершенствования.
Декомпозиция модели
Как только у вас появляется модель, вы можете провести ее декомпозицию на отдельные компоненты. Вам понадобится отыскать математические правила, описывающие взаимодействие этих компонентов. Иногда вклад компонента в конечный результат выражается одной величиной. Некоторые компоненты могут объединять несколько факторов, тогда как другие могут быть более сложными (подобно тем, которые имитируют поток, приходящий к узлу).
Вы обнаружите, что обычно каждый компонент будет обладать параметрами, которые определяют его влияние на модель в целом. На этой стадии достаточно просто обозначить каждый параметр.
Присвоение значения каждому параметру
Как только в вашем распоряжении появились параметры, вы можете пойти напролом и присвоить некое значение каждому из них. На этой стадии вы ожидаете внесения некоторой ошибки. Хитрость состоит в том, чтобы понять, какие параметры оказывают максимальное воздействие на результат, и сосредоточиться на их точном получении. Обычно параметры, чьи значения добавляются к результату, являются менее значительными, чем те, что осуществляют умножение или деление. Удвоение скорости канала связи может увеличить вдвое объем данных, получаемых в течение часа, тогда как добавление транзитной задержки, равной 5 мс, не даст заметного эффекта.
У вас должен иметься обоснованный способ вычисления этих критических параметров. В примере с формированием очереди вы захотели измерить реальную интенсивность входного потока транзакций в существующей системе или найти для измерения подобную систему. Аналогично, вы могли определить время, необходимое для обслуживания запроса, или провести оценку, используя методики, описанные в этом разделе. На самом деле, вам часто придется основывать свою оценку на других вспомогательных оценках. Именно в этом месте и возникают самые большие ошибки.
Вычисление ответов
Только в самом простом случае ваша оценка будет иметь один-единственный ответ. Вы счастливый человек, если можете сказать: «Я могу пройти по городу пять кварталов за 15 минут». Но поскольку системы все усложняются, вам захочется подстраховать ваши ответы. Проведите многократные вычисления, изменяя значения критических параметров, пока не выясните, какие из них действительно управляют моделью. Серьезную помощь в этом может оказать электронная таблица. Затем сформулируйте ваш ответ с точки зрения этих параметров. «Время отклика составляет (грубо) три четверти секунды, если система имеет шину SCSI и объем памяти 64 Мбайт; и одну секунду при объеме памяти 48 Мбайт». (Заметьте, что «три четверти секунды» дает иное ощущение точности, нежели 750 мс.)
Уже на стадии вычислений появляются ответы, которые могут показаться странными. Не спешите игнорировать их. Если ваша арифметика правильна, то, вероятно, ваше понимание проблемы или модель неверны. Это ценная информация.
Отслеживание уровня мастерства
Мы полагаем, что было бы здорово вести учет ваших оценок так, чтобы вы могли оценить, насколько точным был ваш прогноз. Если общая оценка включала в себя вспомогательные, учитывайте и их. Часто будет оказываться, что ваши оценки удачны – на самом деле, спустя некоторое время вы придете к этому.
Если оценка оказывается неверной, не стоит пожимать плечами и уходить. Стоит выяснить, почему она отличалась от предполагаемой. Возможно, выбраны параметры, не соответствовавшие реальной проблеме. Возможно, сама модель была неверной. Какова бы ни была причина, необходимо не спеша прояснить, что же случилось. Если сделать это, то следующая оценка будет лучше.
Обычные правила оценки могут нарушаться перед лицом сложностей и капризов разработки серьезной прикладной программы. Мы считаем, что зачастую единственным способом определения графика выполнения проекта является практический опыт, полученный при работе над этим проектом. Это не обязательно парадокс, если вы практикуете разработку с помощью приращений, повторяя следующие шаги.
• Проверить требования
• Проанализировать риск
• Осуществить проектирование, реализацию, интеграцию
• Проверить правильность при работе с пользователями
Первоначально у вас может быть лишь приблизительная оценка того, сколько итераций понадобится или какова будет их продолжительность. Некоторые методы требуют, чтобы вы зафиксировали это как часть первоначального плана, но для всех методов, за исключением наиболее тривиальных, это будет ошибкой. Если вы не создаете приложение, аналогичное предыдущему, с той же командой и по той же технологии, вам придется делать предположения.
Итак, вы завершаете составление текста программы и проверку исходной функциональной возможности и отмечаете это как конечную точку первого приращения. Основываясь на этом опыте, вы можете уточнить ваше начальное предположение о числе итераций и о том, что может быть включено в каждую из них. С каждым разом уточнение становится все совершеннее, и вместе с этим растет уверенность в правильности графика.
Подсказка 19: Уточняйте график проекта на основе текста программы
Это может не понравиться руководству, которому обычно нужна единственная надежная цифра еще до начала проекта. Вам придется помочь им осознать, что команда, ее производительность и среда будут определять график выполнения. Формализуя эту процедуру и уточняя график (что является частью итерационного процесса), вы сможете дать руководству самые точные оценки графика выполнения, какие только сможете.
Что сказать, если вас просят оценить что-либо
Говорите «Я вернусь к вам с этим позже».
Вы почти всегда можете добиться лучших результатов, если не будете торопиться и потратите некоторое время, чтобы пройтись по всем стадиям, описанным в данном разделе. К оценкам, сделанным на ходу (например, у офисной кофеварки) придется возвращаться вновь и вновь (как, впрочем, и к кофе), теряя при этом покой.
• Скорость алгоритма
• Заведите журнал регистрации сделанных вами оценок. Для каждой оценки укажите, насколько точной она оказалась. Если отклонение превысило 50 %, постарайтесь выяснить, где была допущена ошибка.
9. Спрашивается: какой из двух каналов обладает более широкой полосой пропускания: линия связи со скоростью 1 Мбайт/сек или человек, двигающийся от компьютера к компьютеру со стриммерной кассетой объемом 4 Гбайт в кармане? Какие ограничения накладываются на ответ, чтобы гарантировать его корректность в определенной области? (Например, можно указать, что временем доступа к ленте можно пренебречь.) (Ответ см. в Приложении В.)
10. Так какой же из двух каналов обладает более широкой полосой пропускания? (Ответ см. в Приложении В.)