Основные этапы разработки программного обеспечения. Этапы разработки программного обеспечения

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

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

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

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

1. Быстрая смена вычислительной техники и алгоритмических языков;

2. Не стыковка ЭВМ друг с другом (VAX и IBM);

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

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

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

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

1) постановка задачи;

2) проектирование программы

3) построение модели

4) разработка алгоритма;

5) написание программы;

6) отладка программы;

7) тестирование программы;

8) документирование.

Кратко остановимся на каждом из этих этапов.

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

Как определить решение;

Каких данных не хватает и все ли они нужны;

Какие сделаны допущения и т. п.

Таким образом, кратко можно сказать, что на этапе постановки задачи необходимо:

Описание исходных данных и результата;

Формализация задачи;

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



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

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

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

Методы проектирования архитектуры делятся на две группы:

1)ориентированные на обработку

2)ориентированные на данные.

Методы, ориентированные на обработку , включают следующие общие идеи.

а) Модульное программирование.

Основные концепции:

Каждый модуль реализует единственную независимую функцию;

Имеет единственную точку входа/выхода;

Размер модуля минимизируется;

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

Система в целом построена из модулей.

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

б) Функциональная декомпозиция.

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

в) Проектирование с использованием потока данных.

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

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

г) Технология структурного анализа проекта.

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

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

а) Методология Джексона.

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

б) Методология Уорнера.

Подобна предыдущей, но процедура проектирования более детализирована.

в) Метод иерархических диаграмм.

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

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

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

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

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

Рис. 3.1. Схема построения модели при дедуктивном способе

При дедуктивном подходе (рис. 3.1) рассматривается частный случай общеизвестной фундаментальной модели. Здесь при заданных предположениях известная модель приспосабливается к условиям моделируемого объекта. Например, можно построить модель свободно падающего тела на основе известного закона Ньютона ma = mg – F сопр и в качестве допустимого приближения принять модель равноускоренного движения для малого промежутка времени.

Рис. 3.2. Схема построения модели при индуктивном способе

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

Технология построения модели при индуктивном способе:

1) эмпирический этап

Умозаключение;

Интуиция;

Предположение;

Гипотеза.

2)постановка задачи для моделирования;

3)оценки; количественное и качественное описание;

4)построение модели.

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

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

При дедуктивном подходе рассматривается частный случай общеизвестных алгоритмических моделей. Здесь при заданных предположениях известный алгоритм приспосабливается к условиям решаемой задачи. Например, многие вычислительные задачи линейной алгебры, в частности, нелинейные уравнения, системы алгебраических уравнений и т.п., могут быть решены с использованием известных методов и алгоритмов, для которых существует множество специальных библиотек подпрограмм, модулей. В настоящее время получили распространение специализи-эованные пакеты, позволяющие решать многие задачи (Mathcad, Autocad и т.п.).

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

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

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

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

Композиция – это линейная конструкция алгоритма, составленная из последовательно следующих друг за другом функциональных вершин:

begin S1; S2; end

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

if B then S1 else S2

и неполной развилки:

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

и с постусловием:

repeat S1 until B

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

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

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

Для иллюстрации технологии структурного программирования сверху-вниз рассмотрим пример.

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

На рис. 3.3 проиллюстрирована пошаговая детализация процесса построения алгоритма. Заметим, что для начального шага разработки программы имеем в качестве входных данных коэффициенты а, b, с квадратного уравнения ах 2 + bх + с = 0, а на выходе - значения двух корней х1, х2.

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

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

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

Тестирование - это процесс исполнения программ с целью выявления (обнаружения) ошибок.

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

Тестирование программы как «черного ящика» (стратегия «черного ящика» определяет тестирование с анализом входных данных и результатов работы программы). Критерием исчерпывающего входного тестирования является использование всех возможных наборов входных данных.

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

Разумная и реальная стратегия тестирования - сочетание моделей «черного» и «белого ящиков».

Принципы тестирования:

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

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

Необходимо проверять не только делает ли программа то, для чего она предназначена, но и не делает ли она то, что не должна делать;

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

Инспекция и сквозной просмотр - это набор процедур и приемов обнаружения ошибок при чтении текста.

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

Обращения к переменным, значения которым не присвоены или не инициализированы;

Выход индексов за границы массивов;

Несоответствие типов или атрибутов переменных величин;

Явные или неявные проблемы адресации памяти;

Ошибочные передачи управления;

Логические ошибки.

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

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

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

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

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

Есть золотое правило программистов - оформляй свои программы в том виде, в каком бы ты хотел видеть программы, написанные другими. К каждому конечному программному продукту необходимо документированное сопровождение в виде помощи (help), файлового текста (readme.txt).

Контрольные вопросы

1. Перечислите этапы создания программ.

2. Что выполняется на этапе постановки задачи?

3. Что представляет собой декомпозиция?

4. Какие принципы используются на этапе построения модели?

5. На каких принципах основано структурное программирование?

6. Какие базовые структурные элементы выделяют в структурном программировании?

7. Какие две формы итерации (как элемент структурного программирования) вы знаете?

8. Что собой представляет идея структурного программирования сверху-вниз?

9. Что собой представляет идея структурного программирования снизу-вверх?

10. Что такое отладка программы?

11. Какие классы программных ошибок вы знаете и когда они выявляются?

12. Назначение тестирования программы?

13. Какие способы тестирования вы знаете?

14. Чем отличается стратегия «белого ящика» в тестировании от стратегии «черного ящика»?

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

Рис. 26.1.

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

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

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

■ описание исходных данных и результатов (типы, форматы, точность, способ передачи, ограничения) ;

■ описание задачи, реализуемой программой;

■ способ обращения к программе;

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

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

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

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

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

■ Какая точность представления данных необходима?

■ В каком диапазоне лежат значения данных?

■ Ограничено ли максимальное количество данных?

■ Обязательно ли хранить их в программе одновременно?

■ Какие действия потребуется выполнять над данными?

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

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

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

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

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

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

ВНИМАНИЕ

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ВНИМАНИЕ

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

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

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

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

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

Рис. 26.2.

  • Под типами и форматами не имеются в виду типы языка программирования.

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

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

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

В рамках данного этапа стороны должны осуществить:

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

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

Тестирование и отладка
После достижения задуманного программистами в написанном коде следуют не менее важные этапы разработки программного обеспечения, зачастую объединяемые в одну фазу — тестирование продукта и последующая отладка, позволяющая ликвидировать огрехи программирования и добиться конечной цели — полнофункциональной работы разработанной программы. Процесс тестирования позволяет смоделировать ситуации, при которых программный продукт перестает функционировать. Отдел отладки затем локализует и исправляет обнаруженные ошибки кода, «вылизывая» его до практически идеального состояния. Эти два этапа занимают не меньше 30% затрачиваемого на весь проект времени, так как от их качественного исполнения зависит судьба созданного силами программистов программного обеспечения. Нередко функции тестировщика и отладчика исполняет один отдел, однако самым оптимальным будет распределить эти обязанности между разными исполнителями, что позволит увеличить эффективность поиска имеющихся в программном коде ошибок.

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

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

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

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

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

    Спецификация (определение требований к программе):

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

    Разработка алгоритма:

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

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

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

    Кодирование:

    После проведения спецификации и составления алгоритма решения, используемый алгоритм в итоге будет записан на необходимом языке программирования (Pascal, Delphi, C++ и др.). Результатом этапа кодирования является готовая программа.

    Этапы разработки программы. Отладка:

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

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

    Тестирование:

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

    Создание справочной системы:

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

    Кроме справочной информации справочная система содержит необходимые инструкции по инсталляции программы. Обычно их представляют в виде файла Readme разных форматов: *.doc, *.txt, *.htm. Более подробно рассматриваемый этап разработки программы будет описан позже.

    Создание установочного диска (CD-ROM):

    Инсталяционный диск (CD-ROM) разработчики создают для того, чтобы пользователи могли самостоятельно, без помощи программиста, проинсталировать данную программу на свой ПК.

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

    Введение

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

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

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

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

      Быстрая смена вычислительной техники и алгоритмических языков;

      Не стыковка ЭВМ друг с другом (VAX и IBM);

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

    Этапы технологии программирования

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

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

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

      постановка задачи;

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

      построение модели

      разработка алгоритма;

      написание программы;

      отладка программы;

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

      документирование.

    Кратко остановимся на каждом из этих этапов.

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

      как определить решение;

      каких данных не хватает и все ли они нужны;

      какие сделаны допущения и т. п.

    Таким образом, кратко можно сказать, что на этапе постановки задачи необходимо:

      описание исходных данных и результата;

      формализация задачи;

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

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

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

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

    Методы проектирования архитектуры делятся на две группы:

      ориентированные на обработку

      ориентированные на данные.

    Методы, ориентированные на обработку , включают следующие общие идеи.

    а) Модульное программирование.

    Основные концепции:

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

      имеет единственную точку входа/выхода;

      размер модуля минимизируется;

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

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

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

    б) Функциональная декомпозиция.

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

    в) Проектирование с использованием потока данных.

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

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

    г) Технология структурного анализа проекта.

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

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

    а) Методология Джексона.

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

    б) Методология Уорнера.

    Подобна предыдущей, но процедура проектирования более детализирована.

    в) Метод иерархических диаграмм.

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

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

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

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

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

    Рис. 1. Схема построения модели при дедуктивном способе

    При дедуктивном подходе (рис. 1) рассматривается частный случай общеизвестной фундаментальной модели. Здесь при заданных предположениях известная модель приспосабливается к условиям моделируемого объекта. Например, можно построить модель свободно падающего тела на основе известного закона Ньютона ma = mg F сопр и в качестве допустимого приближения принять модель равноускоренного движения для малого промежутка времени.

    Рис. 2. Схема построения модели при индуктивном способе

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

    Технология построения модели при индуктивном способе:

    1) эмпирический этап

      умозаключение;

      интуиция;

      предположение;

      гипотеза.

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

      оценки; количественное и качественное описание;

      построение модели.

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

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

    При дедуктивном подходе рассматривается частный случай общеизвестных алгоритмических моделей. Здесь при заданных предположениях известный алгоритм приспосабливается к условиям решаемой задачи. Например, многие вычислительные задачи линейной алгебры, в частности, нелинейные уравнения, системы алгебраических уравнений и т.п., могут быть решены с использованием известных иетодов и алгоритмов, для которых существует множество специальных библиотек юдпрограмм, модулей. В настоящее время получили распространение специализи-эованные пакеты, позволяющие решать многие задачи (Mathcad,Autocadи т.п.).

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

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

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

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

    Композиция – это линейная конструкция алгоритма, составленная из последовательно следующих друг за другом функциональных вершин:

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

    if B then S1 else S2

    и неполной развилки:

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

    и с постусловием:

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

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

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

    Для иллюстрации технологии структурного программирования сверху-вниз рассмотрим пример.

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

    На рис. 4.6 проиллюстрирована пошаговая детализация процесса построения алгоритма. Заметим, что для начального шага разработки программы имеем в качестве входных данных коэффициенты а, b, с квадратного уравнения ах 2 +bх + с = 0, а на выходе - значения двух корней х1, х2.

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

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

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

    Тестирование - это процесс исполнения программ с целью выявления (обнаружения) ошибок.

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

    Тестирование программы как «черного ящика» (стратегия «черного ящика» определяет тестирование с анализом входных данных и результатов работы программы). Критерием исчерпывающего входного тестирования является использование всех возможных наборов входных данных.

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

    Разумная и реальная стратегия тестирования - сочетание моделей «черного» и «белого ящиков».

    Принципы тестирования:

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

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

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

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

    Инспекция и сквозной просмотр - это набор процедур и приемов обнаружения ошибок при чтении текста.

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

      обращения к переменным, значения которым не присвоены или не инициализированы;

      выход индексов за границы массивов;

      несоответствие типов или атрибутов переменных величин;

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

      ошибочные передачи управления;

      логические ошибки.

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

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

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

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

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

    Есть золотое правило программистов - оформляй свои программы в том виде, в каком бы ты хотел видеть программы, написанные другими. К каждому конечному программному продукту необходимо документированное сопровождение в виде помощи (help), файлового текста (readme.txt).