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

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

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

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

C труктурное программирование воплощает принципы системного подхода в процессе создания и эксплуатации программного обеспечения ЭВМ. В основу структурного программирования положены следующие достаточно простые положения:

    алгоритм и программа должны составляться поэтапно (по шагам).

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

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

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

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

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

Первая (а ) структура - тип последовательность (или просто последовательность), вторая (б ) – структура выбора (ветвление), третья (в ) – структура цикла с предусловием.

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

«выполнить ; выполнить
»,

если , то выполнить , иначе выполнить
»,

«до тех пор, пока , выполнять »,

где - условие; , ,
- действия.

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

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

В зависимости от типа и числа проверяемых условий различают:

Ветвление с простым условием (условие - выражение отношения);

Ветвление с составным условием (условие - логическое выражение);

Сложное ветвление (несколько условий).

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

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

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

Величина, изменяющая своё значение от цикла к циклу, называется параметром цикла.

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

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

Все циклические процессы по признаку определения количества повторений (М) разделяются на два класса.

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

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

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

    вход в цикл (формирование начального значения параметра цикла);

    вычисления в теле цикла (расчёт текущего значения функций, формирования нового значения параметра цикла, а также вспомогательные операции);

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

В соответствии с видом задания (изменения) параметра цикла арифметические циклы подразделяются на:

    циклы с аналитическим изменением параметра;

    циклы с табличным заданием параметра.

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

Распространены две методики (стратегии) разработки программ , относящиеся к структурному программированию:

– программирование «сверху вниз»;

– программирование «снизу вверх».

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

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

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

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

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

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

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

Достоинства структурного программирования:

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

– повышается эффективность программ (структурирование программы позволяет легко находить и корректировать ошибки, а отдельные подпрограммы можно переделывать (модифицировать) независимо от других);

– уменьшается время и стоимость программной разработки;

– улучшается читабельность программ.

Предпрограммная подготовка задачи

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

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

2. формирование математической модели задачи;

3. выбор и обоснование метода решения;

4. алгоритмизация вычислительного процесса;

5. программирование;

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

7. решение задачи на ЭВМ и анализ результатов;

8. сопровождение программы.

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

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

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

Четкая формулировка цели с указанием вида и характеристик конечных результатов;

Представление значений и размерностей исходных данных;

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

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

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

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

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

Полученная математическая модель должна отвечать следующим требованиям:

Вначале составляется модель исходных данных, затем - расчетные зависимости;

В модели исходных данных не изменяются размерности данных и не используются никакие математические операции;

Обозначение всех входящих в зависимости величин именами, определяющими их суть;

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

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

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

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

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

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

3. Некоторые простые приемы позволяют повысить эффективность программы (то есть уменьшить количество выполняемых операций и время работы программы). К таким приемам относится:

Использование операции умножения вместо возведения в степень;

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

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

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

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

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

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

Обеспечить проверку выполнения всех операций алгоритма;

Свести количество вычислений к минимуму.

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

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

Тестирование - это испытание, проверка правильности работы программы в целом, либо её составных частей.

Отладка и тестирование (англ. test - испытание) - это два четко различимых и непохожих друг на друга этапа:

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

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

Тестирование устанавливает факт наличия ошибок, а отладка выясняет ее причину. В современных программных системах (Turbo Basic, Turbo Pascal, Turbo C и др.) отладка осуществляется часто с использованием специальных программных средств, называемых отладчиками. Эти средства позволяют исследовать внутреннее поведение программы.

Программа-отладчик обычно обеспечивает следующие возможности:

Пошаговое исполнение программы с остановкой после каждой команды (оператора);

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

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

При отладке программ важно помнить следующее:

В начале процесса отладки надо использовать простые тестовые данные;

Возникающие затруднения следует четко разделять и устранять строго поочередно;

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

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

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

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

Очередной тестовый прогон должен контролировать то, что еще не было проверено на предыдущих прогонах;

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

Арифметические операции в тестах должны предельно упрощаться для уменьшения объема вычислений;

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

Минимизация вычислений не должна снижать надежности контроля;

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

Усложнение тестовых данных должно происходить постепенно.

Процесс тестирования можно разделить на три этапа.

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

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

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

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

Как будет вести себя программа, работающая с массивами, если количество их элементов превысит величину, указанную в объявлении массива?

Что произойдет, если числа будут слишком малыми или слишком большими?

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

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

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

Сопровождение программы:

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

Доработка программы для решения конкретных задач;

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

1Конста́нта в программировании - способ адресования данных, изменение которых рассматриваемой программой не предполагается или запрещается.

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

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

3 Инструкция или оператор (англ. statement) - наименьшая автономная часть языка программирования; команда. Программа обычно представляет собой последовательность инструкций.

Многие языки (например, Си) различают инструкцию и определение. Различие в том, что инструкция исполняет код, а определение создаёт идентификатор (то есть можно рассматривать определение как инструкцию присваивания).

Ниже приведены основные общие инструкции императивных языков программирования.

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

Есть три способа, как элементы массива могут быть проиндексированы целыми неотрицательными числами:

первый элемент массива имеет индекс 0;

первый элемент массива имеет индекс 1;

n («индекс началом с n»)

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

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

Применение структурного программирования позволяет увеличить скорость написания программ и облегчить отладку написанной программы . Структурное программирование возможно и на языках программирования assembler, где не предусмотрено структурных операторов, подобных структурным операторам языков программирования C, PASCAL, PL/M.

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

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

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

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

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

Начало информационного этапа

Развитие человечества все больше и больше наталкивало величайшие умы на мысли об автоматизации некоторых процессов. Начало этапа программирования приписывается по разным источникам нескольким периодам в промежутке от начала 19 до середины 20 веков. За эти десятилетия появилось множество методик написания исходного кода. Каждая из них кардинально отличается своими принципами и идеями. Рассмотрим структурное программирование, появившееся в 70-х годах прошлого столетия.

Немного истории

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

Основные принципы структурного программирования

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

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

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

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

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

С разработкой данной методологии стали появляться и развиваться языки программирования. Структурный подход реализуют такие известные из них, как Pascal (Паскаль), C (Си), а также более устаревший - Algol (Алгол).

Эпилог

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

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

Текст программы должен быть таким, чтобы его можно было читать «сверху - вниз». Неограниченное использование операторов безусловного перехода (GO TO ) нарушает это условие, поэтому структурное программирование часто называют программирова­нием без GO ТО.

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

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

Любую программу можно синтезировать на основе элементар­ных базовых конструкций трех типов:

1. Простая последовательность. 2. Условия (альтернативы).

3. Повторение (циклы, итерации). Возможны один из двух или оба вида:

Делать «пока» Делать «пока не»

4. Можно добавить четвертую конструкцию - выбор (пе­реключатель).

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

Перечисленные элементарные конструкции, например, в языке Паскаль реализованы так:

Условный оператор IF лог. выр . THEN оператор 1 ELSE оператор2 ;

IF лог. выражение THEN оператор ;

Повторение (циклы, итерации)

а) Делать «пока» WHILE условие продолжения DO оператор ;

б) Делать «пока не» REPEAT оператор UNTIL условие завершения ;

в) Цикл с перебором FOR К:=В1 ТО В2 DO оператор ;

FOR K:=B2 DOWNTO B1 DO оператор ;

Выбор (переключатель) CASE условие OF

N1, ... Nk : оператор 1 ;

Ni , ... Nm : оператор п ;

END ;

В языке FoxBASE эти конструкции реализованы в виде:

Условный оператор IF лог. выражение

операторы1

[ ELSE

операторы2 ]

ENDIF

Цикл DO WHILE выражение

операторы

ENDDO

Выбор (переключатель) DO CASE

CASE лог . выражение 1

операторы

CASE лог. выражение2

Операторы

CASE лог. Выражение п

Операторы

ENDCASE

Каждая структура характеризуется единственной точкой пере­дачи управ­ле­ния в структуру (единственный вход) и единствен­ной точкой выхода из структуры.

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

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

Структурность программы зависит от используемого языка програм­ми­ро­ва­ния. Современные программные средства раз­работки программ яв­ляются «наи­луч­шими» языками струк­турного программирования. Из рас­простра­ненных языков прог­раммирования самыми подходящими считаются Паскаль, Basic , FoxBASE . Структурное программирование, например, на языке Ассемблер почти невозможно. Сам факт использования языка Ассемблера указывает на то, что программа написана в основном в терми­нах машинного языка.

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

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

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

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

КОНСПЕКТ ОБЗОРНОЙ ЛЕКЦИИ

Для студентов специальности
Т1002 «Программное обеспечение информационных технологий»

(А.М.Кадан , к.т.н., доцент)

Вопрос №34.
Характеристика основных методологий разработки программного обеспечения

1. Методология и технология программирования.

2. Императивное программирование.

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

2.2. Структурное программирование.

3. Метод объектно-ориентированного программирования.

Методология и технология программирования

Приведем основные определения.

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

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

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

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

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

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

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

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

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

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

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

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

Императивное программирование

Императивное программирование - это исторически первая методология программирования, которой пользовался каждый программист, программирующий на любом из «массовых» языков программирования – Basic , Pascal , C .

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

Методы и концепции

· Метод изменения состояний - заключается в последовательном изменении сос тояний. Метод поддерживается концепцией алгоритма.

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

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

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

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

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

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

Императивные языки программирования. Императивные языки программирования манипулируют данными в пошаговом режиме, используя последовательные инструкции и применяя их к разнообразным данным. Считается, что первым алгоритмическим языком программирования был язык Plankalkuel (от plan calculus), разработанный в 1945-1946 годах Конрадом Цузе (Konrad Zuse ).

Наиболее известные и распространенные императивные языки программирования, большинство из которых было создано в конце 50-х - середине 70-х годов XX века, представлены на рисунке. Обратите внимание на пустое место на рисунке, соответствующее 80-м и 90-м годам прошлого века. Это период увлечения новыми парадигмами, и императивных языков в это время практически не появлялось.

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

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

Рекомендации по литературе. Особенности императивного программирования изложены в огромном количестве книг. Наиболее систематично они приведены в работе "Универсальные языки программирования. Семантический подход" [Калинин, Мацкевич 1991].

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

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

Концепции модульного программирования. В основе модульного программирования лежат три основных концепции:

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

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

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

синтаксическая обособленность, т. е. выделение модуля в тексте син таксическими элементами;

семантическая независимость, т. е. независимость от места, где про граммная единица вызвана;

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

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

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

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

потребность организационного расчленения крупных разработок;

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

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

  • Модуль - это совокупность команд, к которым можно обратиться по имени.

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

Функциональная спецификация модуля должна включать:

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

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

Разновидности модулей. Существуют три основные разновидности модулей:

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

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

a) задачи в языке программирования Ada ;

b) кластер в языке программирования CLU ;

c) классы в языках программирования C++ и Java .

3) "Большие” (логические) модули, объединяющие набор "средних" или "маленьких" модулей. Примеры "больших" модулей в языках программи рования:

a) модуль в языке программирования Modula-2;

b) пакеты в языках программирования Ada и Java .

Набор характеристик модуля предложен Майерсом [Майерс 1980]. Он состоит из следую щих конструктивных характеристик:

1) размера модуля;

В модуле должно быть 7 (+/-2) конструкций (например, операторов для функций или функций для пакета). Это число берется на основе представлений психологов о среднем оператив ном буфере памяти человека. Символьные образы в человеческом мозгу объединяются в "чанки " - наборы фактов и связей между ними, запоминаемые и извлекаемые как единое целое. В каждый момент времени человек может обр абатывать не более 7 чанков .

Модуль (функция) не должен превышать 60 строк. В результате его мож но поместить на одну страницу распечатки или легко просмотреть на экране монитора.

2) прочности (связности) модуля;

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

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

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

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

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

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

3) сцепления модуля с другими модулями;

Сцепление (coupling ) - мера относительной независимости модуля от других модулей. Независимые модули могут быть модифицированы без переделки других модулей. Чем слабее сцепление модуля, тем лучше. Рассмотрим раз личные типы сцепления.

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

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

· Сцепление по простым элементам данных.

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

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

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

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

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

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

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

Структурное программирование.

Структурное программирование (СП) возникло как вариант решения проблемы уменьшения СЛОЖНОСТИ разработки программного обеспечения .

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

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

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

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

Подход базируется на двух основных принци пах:

  • Последовательная декомпозиция алгоритма решения задачи сверху вниз.
  • Использование структурного кодирования.

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

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

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

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

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

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

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

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

Теорема о структурировании (Бёма-Джакопини ( Boem - Jacopini )): Всякую правильную программу (т.е. программу с одним входом и одним выходом без зацикливаний и недостижимых веток) можно записать с использованием следующих логических структур ‑ последовательность, выбора и повторение цикла

Следствие 1: Всякую программу можно привести к форме без оператора goto .

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

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

Структурное программирование- это не самоцель. Его основное назначение- это получение хорошей ("правильной") программы, однако даже в самой хорошей программе операторы перехода goto иногда нужны: например - выход из множества вложенных циклов.

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

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

Рекомендации по литературе. Одной из наиболее известных работ в этой области является статья "Заметки по структурному программированию" [Дейкстра 1975]. Методы структурного программирования подробно рассмотрены в книге "Теория и практика структурного прграммирования " [Лингер , Миллс, Уитт 1982]. Практику структурного программирования можно изучать по книге "Алгоритмы + структуры данных = программы" [Вирт 1985]. Философия визуального структурного программирования подробно изложена в работе [Паронджанов 1999].

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

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

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

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

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

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

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

Основные методы и концепции ООП

· Метод объектно-ориентированной декомпозиции – заключается в выделении объектов и связей между ними. Метод поддерживается концепциями инкапсуляции, наследования и полиморфизма.

· Метод абстрактных типов данных – метод, лежащий в основе инкапсуляции. Поддерживается концепцией абстрактных типов данных.

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

Вычислительная модель чистого ООП поддерживает только одну операцию – посылку сообщения объекту . Сообщения могут иметь параметры, являющиеся объектами. Само сообщение тоже является объектом.

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

Синтаксис и семантика

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

В объектно-ориентированном программировании определяют три основных свойства:

Инкапсуляция. Это сокрытие информации и комбинирование данных и функций (методов) внутри объекта.

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

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

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

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

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

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

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

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

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

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

Пример описания в некотором абстрактном Pascal -подобном объектно-ориентированном языке класса «точка», являющегося наследником класса «координаты» может выглядеть так:

Type TCoordinates = class (TObject )

x, y: integer;
Constructor Init (_x, _y: integer);
Function GetX : integer;
Function GetY : integer;
Procedure SetX (_x: integer);
Procedure SetY (_y: integer);
Procedure Move (dx , dy : integer);
Destructor Done; virtual;

Constructor Init();
x:= _x; y:= _y
end;
Function GetX : integer;
begin
GetX := x
end;
. . . . . . . . . . . . .
End;

TPoint = class (TCoordinates )
Color: integer;
Constructor Init (_x, _y, _Color: integer);
Function SetColor (_Color: integer);
Function GetColor : integer;

Constructor Init(_x, _y, _Color: integer);
Inherited Init(_x, _y);
Color:= _Color
end;
. . . . . . . . . . . . .

End ;

Если мы в дальнейшем хотим использовать экземпляры класса TPoint , их необходимо будет создать, вызвав метод-конструктор.

Var P1: Point;

P 1. Init (0,0 , 14); P 1. Move (+2, -2);

Для поддержки концепции ООР были разработаны специальные объектно-ориентирован-ные языки программирования. Все языки OOP можно разделить на три группы.

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

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

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

Литература

ISO/IEC 12207:1995 Information Technology – Software Life Cycle Processes.

[Вирт 1985] – Вирт Н. Алгоритмы + структуры данных = программы. – М.: Мир, 1985

[Дейкстра 1975] – Дейкстра Э. Заметки по структурному программированию // Дал У., Дейкстра Э., Хоар К. Структурное программирование. – М.: Мир, 1975

[Калинин, Мацкевич 1991] – Калинин А.Г., Мацкевич И.В. Универсальные языки программирования. Семантический подход. – М.: Радио и связь, 1991

[Лингер , Миллс, Уитт 1982] – Лингер Р., Миллс Х., Уитт Б. Теория и практика структурного программирования. – М.: Наука, 1990

[Майерс 1980] – Майерс Г. Надежность программного обеспечения. – М.: Мир, 1980

[Паронджанов 1999]- Параноджанов В.Д. Как улучшить работу ума. – М.: Радио и связь, 1999

[Пратт Т., 1979] - Пратт Т. Языки программирования: разработка и реализация. -М .:Мир , 1979

[Шлеер , Меллор 1993] - Шлеер С., Меллор С. Объектно-ориентированный анализ: моделирование мира в состояниях. – Киев: Диалектика, 1993.