Технологии программирования (Software Engineering)
Классические технологические процессы

2.1. Возникновение и исследование идеи

Этот классический процесс имеет следующие действия:

собственно возникновение и первичное исследование идеи, носящее максимально творческий и неформальный характер;

детальное исследование идеи. Выработка концепции. Постановка задачи. Создание "одностраничного описания проекта" и разработка его расширенной версии;

экспертиза идеи специалистами. Принятие решения о начале процесса планирования.

Данный процесс обычно начинается с того, что у человека или небольшой группы людей возникает идея решения проблемы, которая:

препятствует созданию или развитию программного продукта;

приводит к ошибкам в программном продукте.

Предложим несколько советов по организации поиска решения задачи [Косовский, Хитров]

Ждать, пока решение не придет в голову. Лишь при затянувшемся ожидании следует переходить к другим советам. Следует заметить, что особенно эффективен этот совет для ответа на следующие вопросы: "Что такое любовь?", "Что такое старость?".

Следует понять - в чем смысл вопроса. Зачем вообще решать эту задачу? Здесь уместен принцип "выковыривания изюминки" - чтобы начать выковыривать изюминку, надо сначала найти булку с изюмом.

Найти язык чертежей, формул, программ, на котором удается переформулировать задачу. Возможно, при переформулировке что-то станет яснее.

Фиксировать внимание к произвольным мыслям и ощущениям.

Выразить задачу на простом, метафорическом языке. Поиск аналогий может привести к открытию новых фактов.

Эдвард де Боно выделяет два типа мышления с соответствующими подходами решения задач

Вертикальное мышление, которое начинает свой путь от выявления возможной причины той или иной проблемы или затруднения. Далее оно поступательно совершает один логический шаг за другим, пока не придет к некоторому решению.

Непоследовательное мышление, которое может совершить скачок вперед, в сторону, в любое место вообще, чтобы неожиданно выработать решение.

Постановка задачи

Одностраничный документ

Краткий обзор

Введение

Название проекта: Руководство пользователя по OpenMP.

Дата подготовки документа: 19 августа 1998 версия 1.3.

Описание особенностей поставки

Документ "Руководство пользователя по OpenMP" будет доступен как на сервере компании в сети Интернет, так и в бумажной копии.

Поскольку в данной реализации проекта "Волхов" не будут включены все особенности спецификации OpenMP, необходимо четко указать, какие из них будут реализованы, а какие нет.

Полная спецификация по OpenMP доступна в Интернете (http://www.openrap.org/).

Пользователи документа

Сравнительный анализ

Описание технического процесса

Исследовать возможность импортирования спецификаций OpenMP непосредственно из документа.

Определить с помощью инженеров, реализующих поддержку OpenMP, какие особенности спецификации OpenMP войдут в состав текущей версии компилятора.

Разработать проект "руководства" и определить способ его распространения

Проанализировать детали реализации, подготовить и включить в "руководство" соответствующие примеры программ.

Включить информацию о "руководстве пользователя" в документ "Новости компании Компилятор++"

Зависимости

Выяснить возможность подключения инженеров-разработчиков для получения информации о деталях реализации и рецензирования документации.

Выяснить право использовать фрагменты оригинальной спецификации OpenMP

Список основных документов

Спецификация OpenMP.

Основные даты

Завершение проектирования "руководства" - апрель 1998 г.

Первый вариант полного "руководства" - август 1998 г.

Ресурсы

Функция

Инженер-разработчик

Ставка

0.1

Комментарии

Консультирующий инженер, реализующий OpenMP

Технический писатель

Ставка

1.0

Комментарии

Подготовка документа

Руководитель проекта

Ставка

0.3

Комментарии

Управление, разработка плана и содержания

Принятие решения о начале работы над проектом

Подтвердить или поправить все предположения, на которых базируется проект. На основании этих предположений будут делаться все дальнейшие построения.

Выявить и охарактеризовать все критические моменты в проекте. Специалисты должны указать - что не предусмотрено и к каким последствиям это может привести.

2.2. Управление

Управление проектом

При профессиональной разработке программного продукта в крупных фирмах и компаниях предъявляются дополнительные требования к процессу разработки.

Наличие формализованной модели для разработки программного продукта.

Наилучшая расстановка приоритетов и ресурсов.

Принятие ясных и документированных решений.

Соблюдение многочисленных стандартов.

Обеспечение эффективного взаимодействия между командами разработчиков, быстрое создание и вхождение в процесс разработки таких команд.

Тесное взаимодействие с группами поддержки и продаж.

Предпринимательская деятельность фирмы строится исходя из этой задачи, объединяющей пять направлений [Пашкус, Мисько].

Стратегию в области исследования и развития.

Оперативную стратегию.

Финансовую стратегию.

Маркетинговую стратегию.

Стратегию человеческих отношений.

Определим управление как систему принятия решений в области управления фирмой и поделим всех служащих компании на четыре, уровня.

Высший менеджмент. В его задачу входит определение генеральной линии компании.

Управляющие среднего уровня. В их задачу входит координация и стратегическое планирование деятельности структурного подразделения.

Управляющие первичного звена. Одна из важнейших задач этой категории управляющих - планирование на уровне программных проектов. Далее мы сконцентрируемся на изучении обязанностей только менеджеров проекта.

Инженеры. Именно инженеры заняты разработкой и созданием программного продукта.

Лидерами команд разработчиков обычно являются два специалиста, тесно работающих вместе по всем направлениям разработки.

Управляющий проекта - руководитель, обладающий организационными знаниями и опытом.

Технический руководитель проекта - инженер-технолог, обладающий техническими знаниями и опытом.

Обязанности управляющего

Совместная деятельность менеджера и лидера проекта включает:

планирование проекта;

распределение работ;

выбор наилучшей стратегии.

Исключительная ответственность менеджера заключается:

в организации взаимосвязей внутри организации;

в управлении сотрудниками. Менеджер ищет и привлекает лучших специалистов и экспертов для решения возникающих проблем;

в руководстве проектом и контролем его выполнения. Менеджер отвечает за ежедневное руководство данным проектом. Хороший менеджер отводит различные проблемы от группы, он "гасит" нагоняи от заказчика или вышестоящего руководства;

в том, чтобы проект отвечал требованиям заказчика. Руководитель должен держать заказчика в курсе всех событий проекта;

в ответственности за поступление средств.

Еще раз обратимся к понятию "проект" и выделим четыре характеристики, делающих деятельность - проектом [Баранов].

Направленность на достижение конкретных целей. Действительно проекты направлены на получение определенных результатов. Кстати, цели должны быть сформулированы так, чтобы всегда было ясно, что цель достигнута и проект можно заканчивать. Проект обычно предполагает наличие промежуточных целей, которые вместе образуют взаимосвязанный комплекс.

Координированное выполнение взаимосвязанных действий. Здесь следует еще раз вспомнить сложность разработки программного продукта. Взаимосвязи в проекте не всегда очевидны. Некоторые задания должны выполняться строго последовательно, а некоторые - строго параллельно.

Ограниченная протяженность во времени с определенным началом и концом. Проект имеет определенный срок. Иногда этот срок плавающий, например, начинающийся от некоторой еще не определенной даты вступления договора в силу. Проект существует столько времени, сколько его требуется для получения конечного результата.

Уникальность и важность. Уникальность должна объяснять - почему надо создавать данный программный продукт, почему нельзя взять что-то готовое. Элемент важности должен демонстрировать - почему разрабатываемый продукт нужен и важен заказчику, какие нужды и потребности заказчика он покрывает.

Существует ряд психологических принципов, лежащих в основе теории мотивации.

Гедонизм - заинтересованность людей делать то, что им приятно и уклоняться от того, что им неприятно. Менеджер может создать приятную обстановку на работе и таким образом мотивировать подчиненных.

Инстинкты - автоматическая предрасположенность людей вести себя определенным образом. Некоторые люди находят удовольствие в том, чтобы ходить на работу, поскольку "рождены работать".

Концепция побуждений - формирование привычек на основе действий, которые приводили к удовлетворяющему результату в прошлом.

Когнитивная теория - рациональное поведение людей в соответствии с тем, что они думают о будущем. Менеджер может сформировать у работников впечатление о выгодности определенного поведения у подчиненных.

Потребность - осознанная недостаточность чего-либо. Именно потребности заставляют людей действовать определенным образом. Выделяют две основные группы потребностей.

Первичные, являющиеся физиологическими по своей природе.

Вторичные, являющиеся психологическими.

Абрахам Маслоу в 40-х годах XX века разделил потребности на пять категорий.

Физиологические потребности, являющиеся необходимыми для выживания.

Потребности в безопасности, включающие потребности в защите от физических и психологических опасностей и уверенность в выполнении в будущем физиологических потребностей.

Социальные потребности, заключающиеся в привязанности, принадлежности к какой-либо общности, одобрении со стороны других, дружбе.

Потребности в уважении, включающие внутренние и внешние факторы уважения.

Потребность в самовыражении, заключающаяся в самореализации и росте как личности.

Эволюция менеджмента

Особенности европейского менеджмента

Дисциплина, т. е. послушание и уважение к достигнутым соглашениям между фирмой и ее работниками. Дисциплина предполагает также справедливо применяемые санкции.

Вознаграждение персонала, в том числе справедливая зарплата.

Справедливость: сочетание доброты и правосудия.

Корпоративный дух, т. е. гармония персонала, его сплочение.

Подчиненность личных интересов общим. Интересы отдельного работника или группы не должны превалировать над интересами компании.

Особенности американского менеджмента

Анализируй состояние инженеров, запросы рынка, процесс создания программного продукта.

Разделяй обязанности среди подчиненных.

Контролируй исполнение.

Особенности японского менеджмента

Рабочий достаточно разумен, он самостоятельно увеличивает производительность и качество своего труда. Три административных метода помогают претворить этот принцип в жизнь:

кружки качества;

практика стимулирования всех работников к совершенствованию профессиональных умений и навыков. Здесь очень интересно то, что японская традиция "минарай" - наблюдение за опытными рабочими с целью освоения их навыков - очень близка русской традиции наставничества;

практика перевода рабочих с одного места на другое. Работник повышает квалификацию, меняет специализацию и продвигается по служебной лестнице.

Рабочий стремится сделать свою работу лучше. Методы реализации этого принципа:

пожизненный найм работников;

премирование рабочих в случае повышения прибыли фирмы. Заметим, что в неблагоприятной ситуации руководящий состав получает значительно более урезанную зарплату, чем рабочие.

Рабочие образуют "семью". Методы реализации принципа:

работники фирмы оказывают новичку помощь, сочувствие и поддержку, ожидая от него в дальнейшем проявления такого же поведения по отношению к ним;

свободное время работники фирмы проводят вместе;

взаимные обязательства фирмы и рабочих. Если сотрудник фирмы вступает в брак или у него рождается ребенок, то он получает денежную прибавку, поскольку его расходы возросли.

Группа важнее отдельной личности. Этот принцип основан на традиционной японской ценности - никто не должен быть эгоистичным и думать только о себе.

Партнерство и сотрудничество в производственных отношениях.

Особенности российского менеджмента

Социальные права личности.

Честь и достоинство личности.

Согласие и сотрудничество в обществе.

Справедливость, основанная на понимании и принятии правовых норм.

Профессионализм и мастерство. Коллективизм, поддержка и взаимопомощь.

Духовность и психическое здоровье в основе деловой и поведенческой практики.

Методы управления проектами

С помощью этих методик руководитель проекта может:

заблаговременно планировать работу над проектом и предвидеть возможные источники затруднений и задержки выполнения его в срок;

планировать завершение работ в нужные сроки в соответствии с требуемой последовательностью выполнения заданий;

координировать и контролировать выполнение работ для соблюдения календарного графика и завершения проекта в срок.

Следующие два метода были разработаны параллельно и независимо.

Метод Критического Пути (МКП). Метод разработан фирмой "Дюпон де Немур". Первоначально назывался методом Уолкера-Келли, по именам создателей. Позже получил название МКП (СРМ - Critical Path Method).

Метод анализа и оценки программ ПЕРТ (PERT - Program Evaluation and Review Technique). Метод был разработан корпорацией "Локхид" и консалтинговой фирмой "Буз, Аллен энд Гамильтон" и применен в военно-морских силах США для ускорения разработки баллистической ракеты "Поларис" для подводных лодок.

Планирование проекта

Подчеркнем в виде неформальных требований необходимость наличия плана [Баранов 1998].

План помогает создать ясное и четкое понимание - как будущие работы будут выполняться.

План определяет роль каждого человека в исполнении проекта.

План увязывает части работ вместе. План позволяет видеть все взаимозависимости между разными частями работы.

План - это точка отсчета для любых последующих изменений.

С помощью плана мы видим, когда цель, поставленная перед проектом, достигнута и проект заканчивается.

Планирование проекта включает определение ресурсов - человеческих, вычислительных и организационных и составление "карты" задач и времен их выполнения. В стандартном наборе процессов планирование является одним из действий процесса управления. Общий подход к планированию выглядит так:

Построение списка задач.

Составление графиков выполнения работ.

Оценка затрат.

Выделение требуемых ресурсов.

Распределение ответственности.

Определение зависимостей между задачами.

Проведение персональных назначений на задачи.

Определение времени выполнения задачи.

Оценка рисков, связанных с конкретными задачами.

Выявление критических путей.

Создание инфраструктуры управления.

В рамках планирования управляющий решает также организационные задачи:

Анализ документации на полноту, содержание, аккуратность.

Назначение начальной и конечной дат работ.

Определение интерфейсов приложения и планирование работ по детальному проектированию интерфейсов.

Методики оценок времени и затрат

Сверху вниз по крупным блокам аналогичного проекта. Поскольку аналогичный проект пройден и мы знаем реальные затраты для него, то для нового проекта берем соответствующие цифры с некоторыми поправками.

Снизу вверх по составленному графику работ. Данные по трудозатратам и времени берем от исполнителей.

Методика норм работы. Учет ведется по нормам, определяемым как среднее значение времени, уходящее на данную работу в данной компании. Например, время, уходящее на разработку одной строки машинного кода.

Методика исторических соотношений. Стоимость одного проекта относится к стоимости другого пропорционально отношению их объемов в некоторой степени п. Степень n - число, которое надо знать или подобрать опытным путем.

Методика приближенных вычислений. Существует несколько расчетных формул для времен выполнения задач проекта. Введем три оценочных времени - оптимистичное (О), реальное (Р) и пессимистичное (П). Тогда время выполнения задач проекта можно вычислить по:

формуле трапеций: (O+2*Р+П/4;

формуле Симпсона: (О+4*Р+П/б.

Распределение работ

Назначать опытных и квалифицированных людей на наиболее сложные задачи в критическом пути. Людей с меньшим количеством опыта - на менее сложные задачи и т. д.

Определить последовательность работ для каждого исполнителя.

Не перегружать исполнителей задачами, для исполнения которых потребуется больше времени, чем есть в реальности.

Современные подходы к управлению проектом

Для этой организации были сформулированы четыре главных цели ее работы.

Внедрить лучшие практические навыки создания программного обеспечения.

Дать возможность руководителям проектов сфокусировать свои усилия на разработке качественного программного обеспечения, нежели на следовании должностным инструкциям и формальным методикам, которые только ухудшали состояние проекта.

Дать возможность руководителям проектов применять лучшие мировые практические навыки с учетом локальной корпоративной культуры.

Дать возможность быстро изучить и внедрить эти навыки в свою работу с помощью соответствующих методик обучения и программных систем.

Перечислим основные практики.

Формальное управление рисками. Рекомендуется постоянно вести и анализировать списки основных важнейших рисков. У сотрудников не должно быть никаких иллюзий о допустимости рисков.

Согласованность интерфейсов. Интерфейсы - необходимая часть архитектуры. Чем позже будут определены соглашения об интерфейсах, тем больше вероятность того, что систему придется проектировать заново.

Формальные проверки проекта. Экспертизы, проверки, сквозной контроль - все те действия, которые позволяют устранить ошибки как можно раньше.

Планирование и управление на основе метрик. В основу планов и оценок должны быть положены числовые оценки - метрики, накопленные в предыдущих проектах.

Контроль качества на детальном уровне. Промежуточные итоги должны подводиться еженедельно или даже ежедневно.

Свободный доступ к информации о ходе проекта. Проект будет испытывать большие трудности, если менеджер скрывает от остальной команды информацию о состоянии проекта.

Отслеживание причин возникновения ошибок для достижения высокого качества. Ошибки должны быть формально отслеживаемы, каждый случай обнаружения и устранения ошибки должен быть обязательно документирован.

Конфигурационное управление. Использование систем управления исходными кодами, позволяющих отслеживать изменения и дающих возможность вернуться к предыдущим версиям.

Ответственность и подотчетность руководства перед сотрудниками. Такая мотивация сотрудников может значительно повысить производительность труда программистов.

2.7. Эксплуатация и сопровождение

Перечислим четыре основные класса задач, решаемых на этапе сопровождения.

Адаптация, как правило, заключающаяся в модификации функций.

Усовершенствование, заключающееся обычно в добавлении новых функций.

Коррекция или исправление ошибок.

Предупреждение проблем, которые могут возникнуть в будущем.

Для решения указанных задач выбирается один из следующих, наиболее подходящих типов сопровождения [Conger 1994], под которым будем понимать степень вмешательства в программу:

незначительные (локальные) изменения',

реструктурирование кода - повторная разработка небольшой части программы. При этом интерфейс этой части с остальной программой остается неизменным;

реинжиниринг - перестройка существующего программного продукта. Обычно реинжиниринг применяется для приведения кода программы в соответствие с современными методологиями программирования (например, объектно-ориентированной);

программирование заново.

На выбор типа сопровождения влияют два фактора.

Класс решаемой задачи. Как правило, коррекция программы влечет незначительную степень вмешательства, а усовершенствование и адаптация - реструктурирование и реинжиниринг.

Стоимость сопровождения. При высокой стоимости сопровождения рекомендуется ориентироваться на реструктурирование и реинжиниринг, а при низкой - на незначительные изменения.

Существует ряд методов, которые помогают добиться высокого качества сопровождения.

Выделение области связности изменений. Следует четко представлять себе границы области, которая подвергается изменениям.

Самодокументируемость изменений.

Пассивное и активное сопротивление изменениям. За некоторое время до внесения изменения программист должен разослать письмо с описанием изменения и фрагментами изменяемого кода остальным участникам разработки. Программист сможет внести изменения только в следующих случаях:

если никто из коллег не выступит против (в случае пассивного сопротивления);

если все одобрят изменение (в случае активного сопротивления).

Проиллюстрируем процесс сопровождения на примере таких программ, как компиляторы. Поскольку они имеют ряд особенностей, характерных для их сопровождения [Safonov 1996], то перечислим эти особенности в порядке от более общих к более специфическим.

Функционирование на нескольких аппаратных платформах.

Наличие большого количества пользователей.

Необходимость тщательного тестирования.

Наличие устаревших алгоритмов.

Наличие стандартов на языки программирования.

Источниками ("возбудителями") основных классов задач сопровождения могут быть:

пользователи компилятора, находящие ошибки;

разработчики взаимозависимых компонентов (например, отладчика);

инженеры, сопровождающие компилятор (например, предлагая повысить эффективность компилятора).

Теперь рассмотрим - как четыре основных класса задач по сопровождению решаются применительно к компиляторам.

Адаптация компиляторов предполагает их приспособление к изменившимся условиям работы системы. Все причины изменений могут быть сведены к трем основным.

Архитектурные изменения. Например, важнейшим типом адаптации является перенос компилятора на другую архитектуру.

Изменения в операционной системе. Например, операционная система может начать поддерживать многопоточное исполнение, начиная с некоторой версии.

Изменения во взаимозависимых компонентах. Например, разработка инкрементального редактора связей, позволяющего вносить незначительные исправления в текст программы и продолжать исполнение без полной перекомпиляции.

Усовершенствование компиляторов предполагает внесение в них изменений в интересах заказчика. Выделим несколько основных направлений усовершенствования.

Повышение эффективности. Например, оптимизация алгоритмов семантического анализа.

Повышение надежности. Информацию к размышлению здесь можно получить после обработки программы на языке С утилитой расширенного синтаксического анализа lint или утилитой поиска ошибок времени исполнения bcheck.

Необходимость соответствия стандарту языка. В случае изменения стандарта или появления комментариев к стандарту, компилятор должен все эти изменения учитывать.

Необходимость соответствия популярному диалекту языка. Как это ни печально, но иногда даже полностью соответствующий стандарту компилятор должен допускать (в специально задаваемом пользователем режиме) обработку конструкций, допускаемых другим популярным компилятором. Обычно это диктуется соображениями экономической выгоды.

Если усовершенствование и адаптация могут быть рассмотрены для многих компиляторов без указания на язык программирования, то коррекция ошибок в большой степени ориентирована на компилятор с конкретного языка программирования. Исключение составляют специфические ошибки оптимизатора и кодогенератора. Лишь небольшое количество исправлений в части анализа может быть одинаково применено ко всему набору родственных компиляторов и, как правило, связано с неверным взаимодействием этой части с компонентами (например, ошибочная генерация информации отладчика).

Предупреждение проблем может быть проиллюстрировано ставшей уже классической "проблемой 2000 года".

2.8. Завершение эксплуатации

Процесс завершения эксплуатации программного продукта несложен, но требует тщательной организационной подготовки. Обычно процесс начинается с того, что пользователи заранее оповещаются о прекращении сопровождения программного продукта. С этого момента пользователи могут продолжать использовать продукт до тех пор, пока не наступит его моральное устаревание. Очень часто невозможность решить хотя бы одну из четырех задач сопровождения приводит к тому, что от продукта приходится отказаться.

2.3. Анализ требований и проектирование

Введение в анализ требований и проектирование

Анализ и проектирование - два достаточно близких и тесно связанных процесса. Они выполняют общую задачу, результатом которой должно стать четкое представление о системе, на основе которого будет создан программный код. Поэтому мы будем их рассматривать совместно, проводя разделение по методологиям - анализ и проектирование на основе структурной методологии и на основе объектно-ориентированной методологии.

Анализ требований - процесс жизненного цикла программы, во время которого требования заказчика уточняются, формализуются и документируются. Основной вопрос, который решается в это время - "Что должна делать будущая система?"

Проектирование - процесс жизненного цикла программы, во время которого исследуется ее структура и взаимосвязи элементов. Проектирование, как правило, является итерационным процессом. Основной вопрос, который решается в это время - "Как система будет удовлетворять полученным требованиям?".

Проектирование должно проводиться на двух уровнях:

Проектирование архитектуры (проектирование системы, проектирование "в большом").

Детальное проектирование (проектирование модулей, проектирование "в малом").

На сегодняшний день в профессиональном программировании применяются две основные методологии - структурная и объектно-ориентированная. На этапе анализа и проектирования нам важно принципиальное различие между этими методологиями, заключающееся в разных способах декомпозиции систем [Вендров 2000].

Структурная (функциональная) декомпозиция рассматривает структуру системы в терминах иерархии функций и передачи информации.

Объектная декомпозиция рассматривает структуру объектов и связей между ними, а также поведение системы в терминах обмена сообщений между объектами.

Отступление "о спецификациях"

В спецификациях программ имеет смысл выделить две существенно отличающиеся части.

Функциональные спецификации, описывающие функцию программы.

Эксплуатационные спецификации, описывающие скорость работы программы, используемые ресурсы, характеристики аппаратуры, специальные требования к надежности и безопасности.

По уровню формализации выделим три класса.

Словесные спецификации, обработка которых может осуществляться обычным текстовым редактором.

Модельные (структурированные) спецификации, которые предполагают построение схем, диаграмм, других информационных структур.

Формальные спецификации, получаемые строгим формальным способом с использованием математических формализмов, которые обеспечивают полное определение семантики.

Существует два основных способа представления спецификаций:

Текстовое представление, которое подходит для словесных и формальных спецификаций.

Представление с помощью информационных объектов. Как правило, таким способом представляются модельные спецификации.

Отступление "об архитектуре"

И, наконец, еще одно определение содержится в работе [Буч, Рамбо, Джекобсон 2000]: Архитектура - это совокупность существенных решений, касающихся:

организации программной системы;

выбора структурных элементов, составляющих систему, и их интерфейсов;

поведения этих элементов, определенного в процессе взаимодействия с другими элементами;

составления из этих структурных и поведенческих элементов все более и более крупных подсистем;

архитектурного стиля, направляющего и определяющего всю организацию системы: статические и динамические элементы, .их интерфейсы, кооперации и способ их объединения.

Выделяют следующие классы архитектур программных продуктов [Майерс 1980], такие как:

цельная (монолитная) программа;

комплекс автономно выполняемых программ;

слоистая программная система;

коллектив параллельно выполняемых программ.

Можно определить четыре структуры, которые в совокупности описывают программную архитектуру [Ахтырченко, Леонтьев 2001].

Логическая (концептуальная) структура, включающая множество абстракций, необходимых для описания функциональных требований к системе на абстрактном уровне (уровне, не затрагивающем вопросы реализации). Данная структура строится на основе анализа проблемной области.

Модульная структура, определяющая организацию программного средства как совокупности модулей - программных единиц, с которыми могут быть соотнесены рабочие задания, выполняемые членами проектной команды.

Процессная структура, описывающая поведение системы во время ее исполнения.

Физическая структура, определяющая отображение элементов программного средства на аппаратное обеспечение.

Кроме этих четырех часто используются и другие структуры.

Структура вызовов.

Структура потоков данных.

Структура потоков управления.

Структура использования.

Структура классов.

Мэри Шоу (Mary Shaw) и Дэвид Гарлан (David Garlan) предложили использовать каталог архитектурных стилей [Shaw, Garlan 1996].

Независимые компоненты:

взаимодействующие процессы;

системы с событиями: неявный вызов и явный вызов.

Поток данных:

пакетно-последовательный;

каналы и фильтры.

Централизованные данные:

хранилище;

классная доска.

Виртуальные машины:

интерпретатор;

системы с правилами.

Вызов с возвратом:

главная программа и подпрограммы;

объектно-ориентированный;

слойный.

Отступление "о классификации всего сущего"

Большинство окружающих нас объектов относится к категориям, рассмотренных в книге [Шлеер, Меллор 1993].

Реальные объекты - абстракции фактически существующих предметов в физическом мире.

Роли - абстракции цели или назначения человека, части оборудования или организации.

Инциденты - абстракции чего-то произошедшего или случившегося.

Взаимодействия - объекты, получающиеся из отношения между другими объектами.

Классифицировать можно даже ненаблюдаемые объекты. Их можно разбить на четыре категории, расположенные в порядке убывания научного интереса, который они представляют [Физики 1968].

Явления, ненаблюдаемые по определению (например, невидимый свет).

Явления, ненаблюдаемые в принципе (например, абсолютная скорость).

Явления, ненаблюдаемые в природе (например, потомство от стерильных кроликов).

Явления, ненаблюдаемые в обществе воспитанных людей (например, ковыряние в носу).

Проектирование архитектуры (проектирование "в большом")

Структурная методология

Проектирование архитектуры (проектирование "в большом") для структурной методологии включает следующие основные методы:

метод нисходящего проектирования;

метод восходящего проектирования;

метод расширения ядра.

Метод нисходящего проектирования представляет собой подход функциональной декомпозиции на основе двух стратегий.

Пошагового уточнения - при котором на каждом следующем этапе декомпозиции определяются модули очередного, более низкого уровня.

Анализа сообщений - при котором анализируются потоки данных, обрабатываемые модулями.

Объектно-ориентированная методология

Проектирование архитектуры для объектно-ориентированной методологии включает следующие основные методы [Шлеер, Меллор 1993]:

метод проектирования предметных областей;

метод наведения мостов.

Проектирование модулей (проектирование "в малом")

Структурная методология

Перечислим основные методы проектирования модулей для структурной методологии и рассмотрим подробно некоторые из них.

Диаграммы "сущность-связь".

Структурные карты.

Диаграммы деятельности.

Диаграммы Варнье-Орра.

Диаграммы переходов состояний.

Блок-схемы.

Схемы экранов.

Псевдокод.

При создании таких моделей рассматривают понятия:

Сущность - это такая абстракция множества объектов реального мира, в которой все предметы этого множества имеют одинаковые характеристики и согласованы с одним и тем же набором правил и линий поведения. Выделяют следующие типы сущностей:

независимая сущность представляет независимые данные, которые всегда присутствуют в системе. Отношения с другими сущностями у нее могут отсутствовать;

зависимая сущность представляет данные, зависящие от других сущностей в системе. Она всегда имеет отношения с другими сущностями;

ассоциированная сущность представляет данные, которые ассоциируются с отношениями между двумя и более сущностями.

Отношение связывает две или большее количество сущностей. Отношение всегда выражается действием, и его именуют с помощью глагола. Выделяют следующие типы отношений:

неограниченное отношение представляет собой безусловное отношение, которое существует до тех пор, пока существуют относящиеся к делу сущности;

ограниченное отношение представляет собой условное отношение между сущностями;

существенно-ограниченное отношение используется, когда соответствующие сущности взаимозависимы в системе.

Связи используются для идентификации требований, в соответствии с которыми сущности вовлекаются в отношения. Каждая связь соединяет сущность и отношение и может быть направлена только от отношения к сущности. Пара значений связей, принадлежащих одному и тому же отношению, определяет тип этого отношения. Для большинства приложений достаточно использовать следующие типы отношений:

1:1 (один-к-одному);

1:М (один-ко-многим);

M:N (многие-ко-многим);

Атрибут - абстракция одной характеристики, которой обладают все абстрагируемые как объект сущности. Атрибуты бывают:

описательные - представляющие факты, внутренне присущие каждому экземпляру объекта;

указательные - для дачи имени или обозначения экземпляру;

вспомогательные - для связи экземпляра одного объекта с экземпляром другого.

Объектно-ориентированная методология

Перечислим основные методы проектирования модулей для объектно-ориентированной методологии и рассмотрим подробно некоторые из них.

Диаграммы кооперации.

Диаграммы компонентов.

Диаграммы развертывания.

Кооперация служит для обозначения множества взаимодействующих с определенной целью объектов. Кооперация может быть представлена на двух уровнях.

Спецификации, показывая роли классификаторов и ассоциаций в рассматриваемом взаимодействии.

Примеров, указывая экземпляры и связи, образующие отдельные роли в кооперации.

Методы анализа и построения спецификаций

Структурная методология

Перечислим основные методы ведения структурного анализа и рассмотрим подробно некоторые из них.

Диаграммы потоков данных.

Диаграммы потоков управления.

Таблицы решений.

Сети Петри.

Диаграммы зависимости.

Диаграммы декомпозиции.

Диаграммы функционального моделирования.

Компонентами диаграммы потоков данных являются:

внешние сущности - материальный предмет или физическое лицо, представляющее собой источник или приемник информации;

процессы - совокупность операций по преобразованию входных данных в выходные в соответствии с определенным алгоритмом;

накопители данных - абстрактное устройство для хранения информации, которую можно в любой момент поместить в накопитель и через некоторое время извлечь;

поток данных - механизм, определяющий информацию, передаваемую через некоторое соединение от источника к приемнику.

В состав диаграммы входят:

блоки, изображающие активность моделируемой системы;

дуги, связывающие блоки вместе и изображающие взаимодействия и взаимосвязи между ними. Место соединения дуги с блоком определяет тип интерфейса:

управляющая информация входит в блок сверху;

входная информация, подвергающаяся обработке, показана с левой стороны блока;

результаты (выходная информация) показаны с правой стороны;

механизм (человек или автоматизированная система), который осуществляет операцию, представляется дугой, входящей в блок снизу.

Объектно-ориентированная методология

Перечислим основные методы ведения объектно-ориентированного анализа и рассмотрим подробно некоторые из них.

КОК-карты (класс-ответственность-кооперация).

Диаграммы вариантов использования.

Диаграммы классов.

Диаграммы состояний.

Диаграммы деятельности.

Диаграммы последовательности.

Карты класс-ответственность-кооперация (class-responsibility-collaboration) предназначены для описания классов. Первоначально они были созданы для обучения объектному языку

Ответственность - это высокоуровневое описание функций, которые выполняет класс. Здесь применяется идея отказаться от описания конкретных элементов данных и процессов и вместо этого несколькими предложениями описать ответственность класса.

Кооперация - ссылка на другие классы, с которыми необходимо кооперироваться для реализации функций. С помощью коопераций можно получить представление о связях между классами.

Класс служит для обозначения множества объектов, которые обладают одинаковой структурой, поведением и отношением с объектами из других классов. Между классами существуют четыре типа отношений.

Ассоциации, представляющие некоторое отношение или связь.

Обобщения, представляющие иерархическое строение и наследование классов.

Зависимости, когда изменение одного элемента может потребовать изменения другого.

Агрегации (часть-целое), когда один из классов представляет собой некоторую сущность, включающую в себя в качестве составных частей другие сущности.

Диаграмма вариантов использования (use case diagram) - сценарий, позволяющий лучше понять требования к системе. В состав диаграммы входят:

вариант использования (use case) - типичное взаимодействие пользователя и системы. Оно охватывает некоторую очевидную для пользователя функцию, решая некоторую дискретную задачу;

актер (actor) - любая внешняя по отношению к моделируемой системе сущность, которая взаимодействует с системой и использует ее функции и возможности;

интерфейс - спецификация параметров системы, которые видимы извне без указания их внутренней структуры.

Диаграмма состояний (statechart diagram) отражает модель поведения объектов в реальном или абстрактном мире. Все объекты имеют некоторый срок жизни:

сначала они появляются или создаются;

затем эволюционируют, проходя через определенные стадии существования;

и, наконец, исчезают или умирают.

Для представления этого жизненного цикла предлагается модель состояний, состоящая из:

множества состояний; состояние - положение объекта, в котором применяется определенный набор правил, линий поведения, предписаний и физических законов;

множества событий; событие - абстракция инцидента или сигнала в реальном мире, который сообщает о перемещении чего-либо в новое состояние;

множества правил переходов; правила определяют, какое новое состояние достигается, когда с объектом в данном состоянии происходит некоторое событие;

множества действий; действие - это деятельность или операция, которая должна быть выполнена экземпляром, когда он переходит в некоторое состояние.

Процессы могут быть объединены в четыре основных группы.

Процессы доступа, единственная цель которых заключается в получении доступа к элементам одного архива данных объекта.

Генераторы событий, создающие событие, как результат работы.

Процессы преобразования, основной целью которых является вычисление или преобразование данных.

Процессы проверки, которые проверяют условие и исполняют один из нескольких условных выводов управления.

Диаграмма имеет два измерения.

Слева направо, в виде линий жизни каждого объекта, участвующего во взаимодействии. Есть начальный момент времени - верхняя часть диаграммы, где указываются имена объектов.

Сверху вниз, в виде вертикальных линий, представляющих линию жизни отдельного объекта. Линия жизни - время, в течение которого объект существует в системе.

Существуют четыре разновидности сообщений.

Для вызова процедур, выполнения операций или обозначения отдельных вложенных потоков управления.

Для обозначения простого (не вложенного) потока управления.

Для асинхронного сообщения между двумя объектами в некоторой процедурной последовательности.

Для возврата из вызову процедуры.

Подходы к ведению анализа и проектирования

Структурная методология

Итак, комбинации структурных методов образуют структурные подходы. Можно выделить три группы структурных подходов на основе порядка построения модели [Калянов 1996].

Процедурно-ориентированные подходы, в которых первично проектирование функциональных компонентов.

Подходы, ориентированные на данные. Для таких подходов первичны входные и выходные данные, а функциональные (процедурные) компоненты вторичны.

Информационно-ориентированные подходы. Эта группа близка к предыдущей, но отличается тем, что работа ведется с неиерархическими структурами данных.

Как правило, подходы используют две основные группы средств моделирования [Вендров 2000].

Диаграммы, иллюстрирующие функции, которые система должна выполнять, и связи между функциями, например, диаграммы потоков данных и функционального моделирования.

Диаграммы, моделирующие данные и их отношения. Например, диаграммы "сущность-связь".

Перечислим основные подходы к ведению структурного анализа и проектирования и рассмотрим подробно некоторые из них.

Подход Йордона и ДеМарко.

Подход Гейна-Сарсона.

Подход Константайна.

Подход Джексона.

Подход Варнье-Орра.

Подход Мартина.

Подход промышленной технологии DATARUN.

Подход промышленного метода Oracle.

В нем интегрированы следующие средства:

диаграммы потоков данных;

словари данных, являющиеся каталогами всех элементов данных, присутствующих в диаграммах потоков данных;

мини-спецификации обработки, описывающие процессы нижнего уровня. Фактически, мини-спецификации представляют собой алгоритмы описания задач, выполняемых процессами.

Подход Гейна-Сарсона (Chris Gane and Tom Sarson) очень близок к предыдущему. Статистика утверждает, что он применяется в 20,2% случаев [Калянов 1996]. Главной отличительной чертой подхода является наличие этапа моделирования данных, определяющего содержимое хранилищ данных в диаграммах потоков данных в третьей нормальной форме. Этот этап включает:

построение списка элементов данных, располагающихся в каждом хранилище данных;

анализ отношений между данными и построение соответствующей диаграммы связей между элементами данных;

представление всей информации по модели в виде связанных нормализованных таблиц.

Подход Джексона (Michael Jackson) ориентирован на данные. Базовая процедура проектирования включает четыре этапа [Калянов 1996], [Кинг 1991].

Этап проектирования данных. Построение системной сетевой диаграммы, демонстрирующей все хранилища, источники и стоки данных в программе. Представление каждой входной и выходной структуры данных древовидной структурной диаграммой.

Этап проектирования программ. Формирование структуры программы комбинированием структур данных. Идентификация всех связей между компонентами структур данных.

Этап проектирования операций. Построение списка операций, необходимых для продуцирования выходных структур данных из входных. Назначение операций компонентам структуры программы.

Этап проектирования текстов. Трансляция построенной модели программы в текстовый вид с добавлением ряда логических условий для управления выполнением циклов и выбором данных.

Объектно-ориентированная методология

Перечислим основные подходы к ведению объектно-ориентированного анализа и проектирования и рассмотрим подробно некоторые из них.

Подход на основе языка UML.

Подход Шлеер-Меллора.

Подход Град и Буча.

Подход Джеймса Рамбо (Object Modelling Technique - ОМТ).

Подход Ивара Якобсона (Object-Oriented Software Engineering - OOSE).

Подход на основе универсального языка моделирования UML (Unified Modeling Language) включает следующие основные типы диаграмм:

диаграммы вариантов использования;

диаграммы классов;

диаграммы состояний;

три диаграммы поведения (две последние из них также называют диаграммами взаимодействия):

диаграммы деятельности;

диаграммы последовательности;

диаграммы кооперации;

две диаграммы реализации:

диаграммы компонентов;

диаграммы развертывания.

Во время второй фазы - фазы исследования - должна быть создана модель предметной области. Для этой цели наиболее естественно подходят следующие типы диаграмм:

диаграммы вариантов использования;

диаграммы классов;

диаграммы деятельности.

На третьей фазе - построения - продолжается итеративная работа с такими типами диаграмм, как:

диаграммы классов;

диаграммы деятельности.

К ним добавляются следующие типы диаграмм, которые определяют взаимодействие:

диаграммы последовательности;

диаграммы кооперации.

Существует несколько рекомендаций, связанных с данным подходом:

не следует стремиться к построению диаграмм всей системы;

80% проектов можно воплотить, используя 20% средств языка UML. Как правило, наиболее часто используют диаграммы классов и диаграммы деятельности.

Подход Шлеер-Меллора (Sally Shlaer and Stephen Mellor) использует три группы средств для создания модели предметной области.

Информационное моделирование - для определения отношений между данными (информацией). При этом используется один тип диаграмм: Диаграммы классов.

Моделирование состояний - для определения, зависящего от времени поведения системы. Используются диаграммы состояний.

Моделирование процессов - для определения функций, которые система должна выполнить. Используются:

диаграммы деятельности;

диаграммы последовательности.

Для анализа больших предметных областей используются диаграммы, по смыслу близкие к следующим диаграммам языка UML:

диаграммы кооперации;

диаграммы компонентов;

диаграммы развертывания.

Подход предлагает механизм поддержки моделей состояний. Для этого вводятся четыре архитектурных класса.

Переход, описывающий каждый переход для всех моделей состояний в программе.

Конечная модель состояний, связывающая все экземпляры перехода, которые составляют одну модель состояний.

Активный экземпляр. Это абстрактный класс, из которого все экземпляры, имеющие модель состояний, наследуют их текущее состояние.

Таймер, обеспечивающий механизм функционирования таймеров на основе аппаратных средств, доступных для хранения следа времени.

2.4. Программирование (реализация)

Стиль программирования

Это не набор обязательных правил, установленный раз и навсегда. Брайан Керниган (Brian Kernighan) и Роб Пайк (Rob Pike) [Керниган, Пайк 2001] уточняют, что код должен быть прост и понятен, т. е. обладать следующими свойствами:

очевидная логика;

естественные выражения;

использование соглашений, принятых в языке разработки;

осмысленные имена;

аккуратное форматирование;

развернутые комментарии;

отсутствие хитрых трюков и необычных конструкций.

Структура файлов

Приведем рекомендации по именованию файлов.

Заголовочные файлы должны иметь расширение h. Файлы с программой на языке С должны иметь расширение с, а с программой на языке C++ - ее (в операционной системе Unix) или cpp (в операционной системе Windows).

Имена файлов должны отличаться уже первыми восемью символами. Обоснование: Некоторые устаревшие, но, тем не менее, широко используемые операционные системы накладывают ограничения на длину имени файлов.

Все файлы должны иметь различные имена, даже если они находятся в разных каталогах.

Опишем рекомендации по длине строк.

Строки не должны быть длиннее 80 символов. Обоснование: Многие текстовые редакторы и системы печати текстов программ ориентированы именно на это максимальное количество символов в строке. Исторически это объясняется текстовым режимом отображения символов на экране: 25 строк по 80 символов.

Лучше всего, если длина строк программы значительно короче 80 символов.

Далее представлены рекомендации по организации файлов.

Следует соблюдать следующий порядок в заголовочных файлах программы на языке C++:

комментарий к файлу, который оформляется как блочный комментарий. Комментарий может начинаться указанием на лицензию, которая определяет права собственности на данный файл. Комментарий обычно продолжается идентификационной строкой системы управления версиями файлов. Например, для утилиты SCCS (см. 'разд. 5.6.1.1) строка может выглядеть так: %Z%%M% %I% %E% и включать символы идентификации SCCS, имя файла, номер версии и дату последней модификации. Комментарий должен содержать краткое описание файла;

защитная проверка, гарантирующая компиляцию данного файла один единственный раз, вне зависимости от числа его включений в модуль компиляции.

импортируемые интерфейсы. Как правило, они определяются с помощью tinciude-директив;

объявления;

завершающая защитную проверку директива условной компиляции

Для файлов кода на языке C++ рекомендуется такая последовательность:

комментарий к файлу;

импортируемые интерфейсы;

Лексические соглашения

Не начинайте и не заканчивайте идентификаторы символом подчеркивания.

Не используйте идентификаторы, состоящие только из прописных букв. Исключения составляют имена констант и макроопределений.

Не следует в одной и той же программе использовать имена, различающиеся лишь написанием букв - строчной или прописной.

Разделяйте части идентификаторов символом подчеркивания, а не написанием с большой буквы очередной части идентификатора.

Идентификаторы должны начинаться со строчной буквы. Опишем соглашения об именовании.

Смысл всех имен должен быть понятен при чтении программы.

Имена, используемые в ограниченном контексте, могут быть очень короткими. Традиционно имена i и j используются для обозначения счетчиков, р и q для указателей, s для строковых, a ch для литерных переменных. В данном случае ясность достигается краткостью.

Длинные имена могут быть сокращены. Следует придерживаться либо удаления несущественных суффиксов, либо удаления всех гласных букв кроме начальной, либо использования нескольких первых букв слова.

Имена функций должны быть активными, т. е. базироваться на активном глаголе, за которым следует существительное.

Имена перечислимых типов могут иметь единый префикс. Приведем рекомендации по употреблению комментариев.

Блочные комментарии следует применять для описания дополнительной информации о файле, классе, функции или переменной.

Строковые комментарии следует использовать для коротких заметок в одну-две строки.

Языковые детали

Рекомендации по выравниванию.

Стандартная величина отступа равна четырем пробелам.

Табуляционный отступ равен восьми пробелам.

Рекомендации по написанию выражений.

Бинарные операторы должны быть отделены от операндов одним пробелом.

Унарные операторы не следует отделять от операнда пробелом, если только этого не требуют правила языка.

Используйте скобки, чтобы улучшить читаемость. Не следует добавлять пробелы к введенным скобкам.

Старайтесь размещать выражение на одной строке.

Если выражение переносится на следующую строку, то знак бинарной операции следует оставить на первой строке.

Рекомендации по объявлению переменных.

В каждом объявлении должна объявляться только одна переменная.

Объявление переменной должно занимать одну строку.

За типом переменной должны следовать пробел, имя переменной и комментарий с кратким описанием переменной.

Если переменная является указателем, то символ * следует присоединять к типу.

Рекомендации по написанию определения функций.

Определение должно начинаться заголовком функции, за которым идут комментарий, описывающий назначение функции, и собственно тело функции.

Открывающая и закрывающая фигурные скобки, определяющие тело функции, располагаются в первом столбце строк.

Заголовок состоит из типа возвращаемого функцией значения, пробела, имени функции, за которым без пробела следует открывающая круглая скобка для списка параметров.

Если функция статическая, то ключевое слово static должно быть вынесено в строку, предшествующую заголовку функции.

Определение функции всегда начинается в самом левом столбце файла.

Различные части функции следует отделять пустой строкой. Рекомендации по написанию условного оператора.

По одному пробелу следует оставлять перед и после круглых скобок условия.

Открывающая фигурная скобка должна находиться на той же строке, что и закрывающая круглая.

Закрывающая фигурная скобка находится на том же уровне отступа, что и начало условного оператора.

Если условие не помещается на одной строке, то его продолжение на следующей строке должно начинаться в том же столбце, что и первый символ выражения первой строки.

Если часть then или else состоит из простого оператора, то открывающая и закрывающая фигурные скобки могут быть опущены.

Защитное программирование

Существуют три основных принципа защитного программирования.

Общее недоверие. Для каждого модуля входные данные должны тщательно анализироваться в предположении, что они могут быть ошибочными.

Немедленное обнаружение. Каждая ошибка должна быть выявлена как можно раньше, это упрощает установление ее причины.

Изолирование ошибки. Ошибки в одном модуле должны быть изолированы так, чтобы не допустить их влияние на другие модули.

Теперь дадим несколько рекомендаций по защитному программированию [Тассел 1985].

Делайте проверку области значений переменных.

Выполняйте контроль правдоподобности значений переменных, которые не должны превышать некоторых констант или значений других переменных.

Контролируйте итоги вычислений.

Включайте автоматические проверки (например, контроль переполнения или потери точности).

Проверяйте длину элементов информации.

Проверяйте коды возврата функций.

Выбор языка программирования

На выбор языка программирования влияют четыре основных фактора.

Сравнительная пригодность языка программирования для данной задачи.

Избранная методология. Часто говорят, что язык поддерживает ту или иную методологию. Обычно это означает, что применение этого языка совместно с указанной методологией в совокупности дадут значительно больший эффект.

Степень важности для разработчика многочисленных характеристик и свойств, которые могут быть присущи или не присущи избираемому языку программирования.

Степень знакомства программистов с языком программирования. Результаты исследований говорят о том, что производительность программиста, работавшего на некотором языке более трех лет, возрастает на треть по сравнению с программистом такого же уровня, но без опыта работы на данном языке [Boehm 1981]. Исследование специалистов компании IBM показало даже более существенные результаты. Программисты с длительным опытом программирования на некотором языке имеют производительность в три раза большую, чем программисты с минимальным опытом программирования [Walston, Felix 1977].

2.5. Тестирование и отладка

Введение в тестирование и отладку

Тестирование - процесс выполнения программ с целью обнаружения факта наличия ошибок. Это классическое определение тестирования, принадлежащее Гленфорду Майерсу. Обратим внимание, в определении указан лишь один способ проведения тестирования. Существуют и методы ручного тестирования (например, инспекции и сквозные просмотры программ). Поэтому слова "...процесс выполнения программ..." разумно заменить на "...любая деятельность, выполняемая..."

Отладка - процесс локализации и устранения ошибок.

Тестирование программных продуктов

Существуют две основные стратегии тестирования.

Тестирование программы как черного ящика, при котором программа рассматривается как объект, внутренняя структура которого неизвестна.

Тестирование программы как прозрачного (белого) ящика подразумевает знание исходного кода программы и полный доступ к нему.

Существуют также разновидности тестирования.

Детерминированное тестирование, при котором контролируется каждая комбинация исходных эталонных данных и соответствующая ей комбинация результатов функционирования программ. На практике полное детерминированное тестирование обычно нереализуемо.

Стохастическое тестирование, при котором исходные тестовые данные берутся случайным образом, как правило, с использованием статистического распределения.

Ручное тестирование, которое проводится без исполнения тестируемой программы на компьютере.

Типичные ошибки

Обратим внимание на две категории наиболее распространенных ошибок программистов.

Ошибки общего (несинтаксического) характера, остающиеся в программах после выполнения синтаксического контроля.

Группа логических ошибок. Например, неполный учет возможных условий или неверное указание ветви алгоритма после проверки условия.

Ошибки в циклах. Например, неверные границы начала и конца.

Ошибки при работе с данными.

Ошибки ввода-вывода.

Ошибки в описании переменной. Например, отсутствие инициализации переменной.

Ошибки при работе с массивами.

Отсутствие начального обнуления элементов.

Ошибки специального вида, особенно трудные для диагностирования.

Ошибки при написании параллельных программ. Например, ошибки в расстановках семафоров.

Ошибки, связанные с применением препроцессора.

Ошибки, связанные с неправильным результатом операций.

Исчезающие ошибки.

Тестовые данные

Для тестирования программ методом черного ящика [Канер, Фолк, Нгуен 2000] готовятся определенные группы тестов.

Для тестирования классов эквивалентностей. Классы эквивалентностей позволяют вместо большого количества тестов использовать лишь их небольшое подмножество. Каждый тест представляет набор тестов, на которых программа ведет себя одинаково. Существует два основных типа классов эквивалентностей.

Класс корректных тестовых случаев, отражающих типичную "нормальную" ситуацию.

Класс тестов, содержащих ненормальную ситуацию, т. е. описывающих ситуацию, которой быть не должно.

Для тестирования граничных значений.

Для анализа причинно-следственных связей. Эти тесты применяются для программ, в которых взаимодействуют объекты.

Для тестирования тех утверждений, которые приводятся в документации.

Для оценки результатов тестирования используются эталонные ("золотые") файлы, которые содержат ожидаемые результаты работы программы (эталонные результаты). Основные варианты получения эталонных результатов таковы:

использование справочников;

вычисление вручную;

использование результатов, полученных при помощи другой программы, которой мы доверяем.

Тестовое покрытие - это набор тестов, покрывающих программу (каждый линейный участок). Тестовое покрытие важно знать, чтобы определить участки кода, пропущенные при тестировании

Тестирование программ в процессе разработки

Поскольку в процессе разработки приходится тестировать еще не завершенную программу, все подходы к тестированию делятся на две группы.

Тестирование сверху вниз. Применяется, если программа разрабатывается сверху вниз. В данном случае используются "заглушки" - фрагменты кода, имитирующие еще не написанные части программы.

Тестирование снизу вверх. При этом, как правило, дополнительно должна быть создана небольшая программа - "драйвер", организующая взаимодействие уже написанных модулей.

Отслеживание ошибок

Проблема или ошибка может быть рассмотрена как некоторый объект в системе, который может находиться в одном из восьми состояний.

Проблема или ошибка зарегистрирована.

Выполнен первичный анализ (эксперт подтвердил факт наличия ошибки).

Понятна причина, вызвавшая ошибку.

Выполнен окончательный анализ проблемы или ошибки.

Принято решение о начале работы над исправлением.

Выполнено исправление ошибки.

Исправление интегрировано в основное пространство.

Подтверждено исправление ошибки.

Отладка программных продуктов

Отладка программы - процесс творческий и плохоформализуемый. Тем не менее, основной идее отладки (базирующейся на анализе данных) можно придать вид следующего алгоритма:

Следует начать с изучения уже доступных исходных и результирующих данных.

Сформулировать некоторую гипотезу, которая объясняет получение таких результирующих данных.

Подготовить новые исходные данные и провести эксперимент, который позволит доказать или опровергнуть гипотезу.

Обратим особое внимание на два достаточно простых случая отладки. Их анализ может быть достаточно легко выполнен при помощи пошагового отладчика.

Если программа прекращает работу с порождениями "предсмертного дампа памяти" (core-файла), то практически любой отладчик позволит по этому дампу восстановить динамический стек вызовов процедур и локализовать место проблемы.

Если программа выдает некорректное сообщение, то можно получить динамический стек в отладчике, взяв за точку останова вызов функции выдачи сообщения. Стек может дать достаточное количество информации к размышлению.

2.6. Ввод программы в действие

Существует три основных способа доставки программы до пользователя.

Индивидуальная доставка (как правило, разработка для конкретного заказчика).

Коробочная доставка.

Доставка через Интернет.

В последнем случае есть несколько основных разновидностей доставки.

Работа с программой осуществляется через Интернет, как правило, из среды интернет-браузера. Пользователи имеют возможность получить по сети исполняемый код (или его клиентскую часть) и начать работу с самой новой версией данного продукта. С подавляющим большинством таких приложений пользователи работают бесплатно. Однако ряд компаний развивают идею продажи сервисов работы с некоторым программным продуктом за определенную повременную оплату.

Возможность скачать из сети программу и установить ее на своих компьютерах, подобно установке программы, поставляемой в коробке. Интернет неожиданно просто решает проблему распространения программного обеспечения и доставки его до пользователя. На смену десятилетию "коробочных продуктов" (1985-1995) пришли "продукты из Интернета". Причем в Интернете есть две группы программных продуктов:

свободно распространяемые программные продукты;

коммерческие программные продукты. На последние сначала можно получить временный регистрационный ключ (как правило, срок его действия около месяца), самостоятельно выяснить достоинства и недостатки продукта и принять решения о необходимости пользоваться им в дальнейшей работе. Если программный продукт подходит для пользователя, то он может получить постоянный регистрационный ключ после оплаты стоимости программного продукта.

Следует отметить, что в целом ряде случаев (например, работа с программой через Интернет) такое действие, как инсталляция (установка) программы, уходит в прошлое. Тем не менее, приведем правила хорошего тона при подготовке инсталляции.

Следует, даже пользуясь инсталлятором, который упаковывает программу в один самораспаковывающийся файл, дополнительно сжимать его и распространять именно zip-архив. Не следует использовать другие архиваторы, даже если они сжимают лучше, поскольку их пользователь может не иметь.

Следует всегда включать в архив файл README, который должен содержать подробную информацию о программе. Он должен быть доступен пользователю еще до начала инсталляции.

Следует убедиться, что инсталлятор включает возможность автоматического удаления программы с диска. Программа без деинсталлятора создает массу лишних проблем своим пользователям.