Файл: Основы проектирования программ. Этапы создания программного обеспечения (Анализ требований).pdf
Добавлен: 31.03.2023
Просмотров: 190
Скачиваний: 3
Итак, спецификация – это достаточно точное и полное описание задачи, которое человеку, участвующему в решении, легче написать, понять и прочесть, чем программисту представить решение этой задачи на доступном ему языке программирования.
Как уже говорилось, в процессе проектирования и разработки ПО спецификации занимают промежуточное положение между эскизными требованиями и готовой программой. Дополненные и уточненные требования – это уже спецификация, которая на пути к программе может претерпеть много изменений, оставаясь спецификацией до тех пор, пока не сможет быть выполнена на машине или пока это выполнение не станет достаточно эффективным.
В спецификации программы имеет смысл выделить по крайней мере две существенно разные части.
Одна описывает объекты, действующие в задаче: разбиение задачи на подзадачи; входные и выходные данные, связи между ними, если речь идет о задаче преобразования данных или вычислении функции, процессы и действия, если речь идет о задаче управления или взаимодействия с внешней средой, реакции на исключительные ситуации и т.д. Эта часть называется функциональной спецификацией. Она описывает функцию программы, решающей задачу.
Другая часть спецификации касается таких аспектов, как скорость работы программы или используемые ею ресурсы, характеристики аппаратуры, на которой она должна работать, специальные требования к надежности и безопасности и т.д. Эту часть называют эксплуатационной спецификацией.
Кроме этого, различают "внешние" спецификации, обращенные к внешнему пользователю – потребителю программы, и "внутренние" спецификации, обращенные к внутреннему пользователю – разработчику программы.
Спецификациям уделяется все большее внимание, их разработка рассматривается как самостоятельная область технологии и методологии программирования, а сами они — как существенная часть программной документации. В последнее время появилось большое количество технологий и методов построения спецификаций, а также языков спецификаций.
Проектирование внутренней структуры ПО начинается с изучения спецификаций, разработанных на предыдущем этапе. Первым делом проверяется завершенность спецификаций и формально выявляются все противоречия. Любые возникшие проблемы должны быть обсуждены разработчиками совместно с пользователями. К началу проектирования все спецификации должны быть согласованы с пользователями и не могут произвольно изменяться разработчиком. Далее формируется структура ПО и общие правила взаимодействия его компонентов (модулей).
Модуль - это отдельная функционально законченная программная единица, которая может применяться самостоятельно, либо быть частью программы. ПО создается на основе модульной структуры, состоящей из отдельных модулей.
К преимуществам разработки ПО с использованием модулей можно отнести следующее.
- Упрощается проектирование ПО, так как сложную и большую проблему легче понять, разбив ее на отдельные функциональные части.
- Обеспечивается возможность организации совместной работы больших коллективов разработчиков, так как каждый программист имеет дело с независимой от других частью ПО - модулем или группой модулей.
- Упрощается отладка программ, так как ограниченный доступ к модулю и однозначность его внешнего поведения исключает влияние ошибок в других модулях на его функционирование.
- Повышается надежность программ, так как относительно малый размер модулей и, как следствие, небольшая их сложность, позволяют провести более полную их проверку.
Модуль обладает тремя основными признаками: реализует одну или несколько функций, имеет определенную логическую структуру и используется в одном или нескольких контекстах. Функция представляет собой внешнее описание действий, выполняемых модулем, без указания того, как эти действия производятся. Логика модуля определяет его внутренний алгоритм, т.е. то, как модуль выполняет функцию. Функцию модуля можно рассматривать как совокупность логики модуля и функций всех подчиненных (вызываемых им) модулей. Контекст описывает конкретное использование модуля. Результатом проектирования модульной структуры является определение состава программных модулей и установление связей между ними по управлению и по данным.
Программирование является, пожалуй, наиболее изученным из всех этапов разработки ПО. Программирование хорошо разработанного проекта программы можно отнести к чисто технической работе. И, наверное, поэтому программирование иногда еще называют кодированием. Чрезвычайно важным для правильной организации разработки ПО является понимание того, что хорошие результаты при программировании достигаются в первую очередь за счет высокого качества проекта программы, а не за счет искусного кодирования.
Процесс программирования состоит из следующих шагов.
- Выбор языка программирования. Этот выбор часто бывает предопределен имеющимися у заказчика вычислительными ресурсами, принятыми организационными стандартами и подготовкой программистов. Существенное влияние на выбор языка оказывает его возможности обеспечивать надежный процесс получения программ, наличие и специфические особенности компилятора и т.д.
- Выбор алгоритма и структуры данных. Этот шаг обусловлен тем, что к настоящему времени разработано значительное количество алгоритмов и соответствующих структур данных, которые позволяют удовлетворить многие потребности разработчиков ПО. Поэтому следует использовать опыт предыдущих разработок и выбрать из имеющихся эквивалентных алгоритмов и структур данных необходимые. Если же выбор не приводит к желаемому результату, то алгоритм и структуры данных необходимо разработать.
- Оформление начала и конца будущего модуля. На данном шаге осуществляется оформление модулей в соответствии с требованиями принятого языка программирования.
- Объявление всех данных, используемых в качестве параметров. На этом шаге записываются операторы объявления данных, соответствующие входным и выходным параметрам каждого модуля.
- Объявление оставшихся данных. Данный шаг предусматривает запись операторов объявления всех оставшихся данных, которые должны быть использованы в модуле. Поскольку трудно предсказать все переменные, которые понадобятся, этот шаг часто перекрывается следующим.
- Детализация текста модуля. На этом шаге в результате нескольких итераций осуществляется последовательная детализация логики модуля, начиная с достаточно высокого уровня абстракции и заканчивая готовым текстом программы.
- Окончательное оформление текста программы. На этом шаге текст модуль проверяется еще раз, и при этом вставляются дополнительные комментарии, поясняющие текст программы.
- Проверка правильности программы. На этом шаге в ручную проверятся правильность модуля. Для этого применяют методы статического тестирования (см. следующий раздел).
- Компиляция модуля. Этот шаг отмечает переход от этапа программирования к тестированию модуля, так как работа над созданием модуля завершена. Компилятор, строя машинную программу, проводит контроль синтаксиса и частично семантики исходного текста программы.
Опыт разработки ПО позволил сформулировать ряд правил, способствующих получению корректных, эффективных и доступных для чтения и понимания программ. Приведем некоторые из них.
- Стремитесь к простой, а не сложной программе.
- Четко и ясно выражайте свои мысли.
- Возлагайте рутинную работу на ЭВМ.
- Сначала записывайте программу на легко воспринимаемом языке, а затем переводите ее на требуемый язык программирования.
- Не останавливайтесь на первом варианте программы.
- Выбирайте такой способ представления данных, который упрощает программу.
- Не исправляйте неудачный участок программы - перепишите его заново.
- Убедитесь, что входные данные соответствуют принятым ограничениям.
- Обеспечьте распознавание неверно заданных входных данных и, если это возможно, их исправление.
- Обеспечьте возможность нормального завершения программы в случае неверного задания исходных данных.
- Стремитесь к тому, чтобы инициализация переменных проводилась прежде, чем они будут использованы.
- Стремитесь в первую очередь к получению правильной программы и только потом к сокращению времени ее выполнения.
- Отдавайте предпочтение ясности программы, а не скорости ее выполнения.
- Не оптимизируйте без необходимости. Программы следует писать просто и ясно. Для оптимизации используйте оптимизирующий компилятор.
- Не тратьте зря времени на изменение текста программы для сокращения времени ее работы - ищите лучший алгоритм.
- Помните, что в сложных системах простые последовательные алгоритмы часто работают быстрее, чем более изощренные и сложные.
- Используйте комментарии, поясняющие текст программы.
- Обеспечьте соответствие комментариев тексту программы.
- Комментарий должен не повторять текст программы, а пояснять смысл выполняемых действий.
- Не пытайтесь с помощью комментариев сделать понятной плохую программу - перепишите ее заново.
- Идентификаторы переменных и метки в программе должны нести смысловую нагрузку.
- Избегайте сходных по написанию идентификаторов.
- Не пользуйтесь в качестве идентификаторов ключевыми словами языка программирования.
- Избегайте использования промежуточных переменных там, где без них можно обойтись.
- Во избежание неоднозначности в выражениях употребляйте скобки.
- Записывайте только один оператор в строке.
- Используйте сдвиги по строке в соответствии с уровнем вложенности операторов.
- Избегайте меток операторов, если в этом нет необходимости.
- Используйте строки пробелов для улучшения внешнего вида программы.
- Тестирование и отладка программ
Под отладкой понимается процесс, позволяющий получить программу, функционирующую с требующимися характеристиками в заданной области входных данных. В результате отладки программа должна соответствовать определенной фиксированной совокупности правил и показателей качества, принимаемой за эталонную для данной программы. Процесс отладки включает:
- действия, направленные на выявление ошибок (тестирование);
- диагностику и локализацию ошибок (определение характера и местонахождения ошибок);
- внесение исправлений в программу с целью устранения ошибок.
Отладка заключается в разработке тестов, направленных на выявление наличия ошибок в ПО. Если тестирование не выявило наличие ошибок, то оценивается полнота проведения тестирования. Если тестирование осуществлено в полном объеме, то процесс отладки завершается. Если же тестирование не полно, то разрабатываются новые тесты, и процесс тестирования продолжается. Если тестирование позволило определить наличие ошибок, то осуществляется диагностика этих ошибок, которая заключается в определении причин их возникновения. В лучшем случае диагностика приводит к локализации места положения ошибки в программе и исправлению данной ошибки. Исправление заключается в разработке и реализации корректировки программы. После чего разрабатываются тесты для проверки правильности корректировки. Если же результаты диагностики не позволяют определить место ошибки, то подготавливаются дополнительные тесты, направленные на локализацию ошибки.
Если вспомнить распределение временных затрат по этапам разработки на фазе разработки ПО, то общее время проведения отладки, включая как автономную, так и комплексную составляет 45% затрат. По некоторым оценкам, чисто на тестирование уходит до 40% временных затрат фазы разработки. Следовательно, на тестирование в общем процессе отладки выделяется 87.5%. Остальные 12.5% времени разделяется между процессами локализации и устранения ошибок. В среднем из этих двух аспектов, диагностика и локализация ошибок занимает 95%.
Методы диагностики и локализации ошибок
Среди методов диагностики и локализации ошибок четко выделяются два направления. Это так называемые методы "грубой силы" и методы с обдумыванием результатов.
Наибольшую популярность в программистской среде получили методы "грубой силы". Это вызвано тем, что они не требуют значительного внимания и больших умственных затрат. Методы "грубой силы" можно разделить на 3 категории:
- диагностика и локализация ошибок с использованием дампа памяти;
- метод отладочной печати;
- диагностика и локализация ошибок с использованием программ – отладчиков.
Наименее эффективен из них анализ дампа памяти. С ним связаны следующие проблемы:
- Довольно сложно установить соответствия между ячейками памяти и переменными в исходной программе.
- Обычно анализируется значительный объем данных, многие из которых не используются.
- Дамп является отображением программы в статике, в то время как для успешного обнаружения ошибки прежде всего важна динамика выполнения программы.
- Дамп может не отражать состояния программы в точке, содержащей ошибку, а действия, осуществляемые в промежутка между моментом возникновения ошибки и моментом получения дампа, могут помешать локализовать ошибку.
Метод отладочной печати, при котором операторы отображения значения переменных расставляются по всей программе, считаются более эффективными. Хотя он имеет много недостатков, тем не менее, его использование часто оказывается предпочтительнее использования дампа. Метод отладочной печати позволяет отображать динамику выполнения программы и рассматривать информацию, которую легче поставить в соответствие исходному тексту.
Приведем несколько недостатков этого метода. Во-первых, расстановка операторов отладочной печати носит, как правило, интуитивный характер, и, следовательно, может быть не эффективной. Во-вторых, в процессе отладки может оказаться необходимым проанализировать большое число данных. В-третьих, при этом подходе требуется изменять программу при отладке, а эти изменения могут скрыть ошибку, нарушить критические временные отношения или внести в программу новые ошибки.
В-четвертых, метод отладочной печати не применим для отладки некоторых типов ПО, например, операционных систем, программ управления процессами и т.п.
Метод третьей категории, использующий автоматические средства отладки, подобен методу отладочной печати, но отличаются от него в части внесения изменений в программу. Наиболее существенные недостатки метода диагностики и локализации ошибок с помощью программ отладчиков состоят в отсутствии методологии поиска, то есть в ориентации на метод проб и ошибок, а также в необходимости анализа большого количества избыточных данных.
Общей проблемой методов "грубой силы" является то, что они игнорируют процесс обдумывания условий и причин появления ошибок.