Технологии программирования

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

Рубрика Программирование, компьютеры и кибернетика
Вид реферат
Язык русский
Дата добавления 26.09.2009
Размер файла 76,3 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Министерство образования Республики Беларусь

Учреждение образования

«Гомельский государственный университет имени Ф.Скорины»

Кафедра ВМ и П Математический факультет

Реферат

на тему:

«Технологии программирования»

Выполнила: студентка группы М-52

Сабурова Ю.А.

Принял: Орлов В.В.

Гомель 2006

  • Структурные методы программирования

Особенности структурных программ

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

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

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

- простая стандартная структура управления;

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

- соглашения о стиле кодирования.

Рассмотрим эти характеристики подробнее.

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

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

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

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

- общий обзор программы;

- организация программы;

-операторы программы.

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

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

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

2. Краткое описание базы данных, включая главные файлы и структуры записей.

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

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

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

Элементы блока комментариев для каждого модуля содержат:

- назначение модуля (в одном- двух предложениях);

- алгоритмические особенности, ограничения;

- описание интерфейсов модуля (передаваемые параметры);

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

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

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

- содержательных имен процедур и переменных;

- типовых управляющих конструкций и процедур;

- последовательного, строгого стиля кодирования.

Стандартизация стиля кодирования предполагает выполнение следующих правил:

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

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

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

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

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

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

Цели структурного программирования

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

-создание высококачественных программ с предсказуемым поведением;

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

- упрощение структуры программы и процесса их разработки;

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

- сокращение сроков разработки и снижение стоимости разработки программных систем.

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

1. Улучшить удобочитаемость программ, для этого:

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

- уменьшить сложность программы за счет упрощения путей управления в программе;

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

2. Повысить эффективность программ, для этого:

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

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

3. Повысить надежность программ, для этого:

- конструировать программы так, чтобы отпадала или уменьшалась необходимость отладки;

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

- использовать доказательство корректности программ как часть процесса их конструирования;

- ввести более высокий уровень точности в программировании.

4. Создать дисциплину программирования, для этого:

-систематизировать процесс программирования,

- повысить целостность программной системы,

- заставить программиста думать.

5. Уменьшить стоимость программирования, для этого:

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

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

Программирование с использованием пошаговой детализации

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

Особенности процесса пошаговой детализации следующие:

1. Процесс выполняется в виде последовательности отдельных шагов.

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

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

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

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

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

- множество структур данных:

- множество инструкций;

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

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

Нисходящее и восходящее программирование

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

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

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

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

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

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

Пример разработки

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

Задача. Дано натуральное m. Проверить гипотезу Гольдбаха для всех четных чисел, меньших m.

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

· Вариант 1.

var

i,m: integer;

begin

writeln('Введите натуральное m');

readln(m);

i:=2;

while i<m do

begin

{проверяем гипотезу Гольдбаха для четного числа i}

i:=i+2

end;

end.

· Вариант 2. Вводим функцию gold в виде «заглушки» (пока она еще абсолютно ничего не делает).

var

i,m: integer;

function gold(n:integer):boolean;

{n удовлетворяет гипотезе Гольдбаха <=> значение функции - истина}

begin

end;

begin

writeln('Введите натуральное m');

readln(m);

i:=2;

while i<m do

begin

{проверяем гипотезу Гольдбаха для четного числа i}

if not gold(i)

then writeln(i,' - не удовлетворяет гипотезе Гольдбаха');

i:=i+2

end;

end.

· Вариант 3. Чтобы проверить взаимодействие «заглушки» с основной программой, присваиваем функции gold постоянно ложное значение.

var

i,m: integer;

function gold(n:integer):boolean;

{n удовлетворяет гипотезе Гольдбаха <=> значение функции - истина}

begin

{заглушка}

gold:=false

end;

begin

writeln('Введите натуральное m');

readln(m);

i:=2;

while i<m do

begin

{проверяем гипотезу Гольдбаха для четного числа i}

if not gold(i)

then writeln(i,'- не удовлетворяет гипотезе Гольдбаха');

i:=i+2

end;

end.

· Вариант 4. Только число 4 представляется в виде суммы двух четных простых чисел (4 = 2+2). Все большие четные числа, если удовлетворяют гипотезе Гольдбаха, то представляются только в виде суммы двух нечетных простых чисел. Поэтому уточняем функцию gold: ищем простые числа только среди нечетных и первое проверяемое четное число полагаем равным 6.

var

i,m: integer;

function gold(n:integer):boolean;

{n удовлетворяет гипотезе Гольдбаха <=> значение функции - истина}

var j: integer;

begin

gold:=false;

for j:=3 to n-3 do

if {j и n-j - простые числа} then gold:=true

end;

begin

writeln('Введите натуральное m>=6');

readln(m);

i:=6;

while i<m do

begin

{проверяем гипотезу Гольдбаха для четного числа i}

if not gold(i)

then writeln(i,' - не удовлетворяет гипотезе Гольдбаха');

i:=i+2

end;

end.

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

· Вариант 5. Определяем функцию prime в виде «заглушки».

var

i,m: integer;

function prime(n:integer):boolean;

{n - простое число <=> значение функции - истина}

begin

prime:=true

end;

function gold(n:integer):boolean;

{n удовлетворяет гипотезе Гольдбаха <=> значение функции - истина}

var j: integer;

begin

gold:=false;

for j:=3 to n-3 do

if prime(j) and prime(n-j) then

begin

writeln(n, '=', j, '+', n-j);

gold:=true

end

end;

begin

writeln('Введите натуральное m>=6');

readln(m);

i:=6;

while i<m do

begin

{проверяем гипотезу Гольдбаха для четного числа i}

if not gold(i)

then writeln(i,' - не удовлетворяет гипотезе Гольдбаха');

i:=i+2

end;

end.

· Вариант 6. «Заглушку» в функции prime заменяем полноценным кодом.

var i,m: integer;

function prime(n:integer):boolean;

{n - простое число <=> значение функции - истина}

var

k: integer;

begin

prime:=true;

for k:=2 to n-1 do

if n mod k=0 then prime:=false

end;

function gold(n:integer):boolean;

{n удовлетворяет гипотезе Гольдбаха <=> значение функции - истина}

var j: integer;

begin

gold:=false;

for j:=3 to n-3 do

if prime(j) and prime(n-j) then

begin

writeln(n, '=', j, '+', n-j);

gold:=true

end

end;

begin

writeln('Введите натуральное m>=6');

readln(m);

i:=6;

while i<m do

begin

{проверяем гипотезу Гольдбаха для четного числа i}

if not gold(i)

then writeln(i,' - не удовлетворяет гипотезе Гольдбаха');

i:=i+2

end;

end.

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

· Вариант 7. Оптимизируем функцию prime. Достаточно проверять наличие делителей только среди чисел, не превышающих половины n.

function prime(n:integer):boolean;

{n - простое число <=> значение функции - истина}

var

k: integer;

begin

prime:=true;

for k:=2 to n div 2 do

if n mod k=0 then prime:=false

end;

· Вариант 8. Оптимизируем функцию prime в большей степени. Оказывается, что достаточно проверять наличие делителей только среди чисел, не превышающих корня квадратного из n (действительно, если n = a b, то одно из чисел a или b не больше n1/2).

function prime(n:integer):boolean;

{n - простое число <=> значение функции - истина}

var

k: integer;

begin

prime:=true;

for k:=2 to trunc(sqrt(n)) do

if n mod k=0 then prime:=false

end;

· Вариант 9. Еще раз оптимизируем функцию prime: прекращаем перебирать потенциальные делители n, как только найдем делитель.

function prime(n:integer):boolean;

{n - простое число <=> значение функции - истина}

var

k: integer; p: boolean;

begin

p:=true; k:=2;

while p and (k<= trunc(sqrt(n))) do

if n mod k=0 then p:=false else k:=k+1;

prime:=p

end;

· Вариант 10. Оптимизируем функцию gold - прекращаем выполнять цикл, как только обнаружим, что число удовлетворяет гипотезе Гольдбаха.

function gold(n:integer):boolean;

{n удовлетворяет гипотезе Гольдбаха <=> значение функции - истина}

var j: integer; g:boolean;

begin

g:=false;

j:=3;

while (j<=n div 2) and not g do

if prime(j) and prime(n-j) then

begin

writeln(n, '=', j, '+', n-j);

g:=true

end

else j:=j+2;

gold:=g

end;

· Вариант 11. Пишем окончательную версию функции prime: учитываем, что n - нечетное число. Заметим, что в этой версии функция prime будет правильно работать только для нечетных чисел, а в предыдущих версиях такого ограничения не было.

function prime(n:integer):boolean;

{n - простое нечетное число <=> значение функции - истина}

var

k: integer; p: boolean;

begin

p:=true;

k:=3;

while p and (k<= trunc(sqrt(n))) do

if n mod k=0 then p:=false else k:=k+2;

prime:=p

end;

· Вариант 12. Окончательная версия программы: оптимизируем главную программу; убираем печать из функции gold и вставляем печать в главную программу.

function prime(n:integer):boolean;

{n - простое нечетное число <=> значение функции - истина}

var

k: integer; p: boolean;

begin

p:=true;

k:=3;

while p and (k<= trunc(sqrt(n))) do

if n mod k=0 then p:=false else k:=k+2;

prime:=p

end;

function gold(n:integer):boolean;

{n удовлетворяет гипотезе Гольдбаха <=> значение функции - истина}

var j: integer; g:boolean;

begin

g:=false;

j:=3;

while (j<=n div 2) and not g do

if prime(j) and prime(n-j) then g:=true

else j:=j+2;

gold:=g

end;

var m,i,h :integer;

begin

writeln('Введите натуральное m>=6');

readln(m);

h:=0;

i:=6;

while (i<m) and (h=0) do

begin

{проверяем гипотезу Гольдбаха для четного числа i}

if not gold(i) then h:=i else i:=i+2;

end;

if h=0 then writeln('Гипотеза Гольбаха верна для всех чисел <',m)

else writeln('Гипотеза Гольдбаха не выполнена для ',h)

end.

МОДУЛЬНОЕ ПРОГРАММИРОВАНИЕ

Основные понятия и определения

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

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

2. Разделение сложной проблемы на более мелкие и простые подпроблемы.

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

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

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

Достоинства модульного программирования проявляются в следующем:

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

2. Упрощается тестирование программы.

3. Упрощается процесс обнаружения и исправления ошибок.

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

5. Упрощается процесс повышения эффективности программы.

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

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

Программные модули и схема модуляризации

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

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

Модуль должен обладать следующими свойствами:

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

2. Модуль замкнутый и простой.

3, Модуль дискретен и обозрим.

4. Модуль отдельно тестируется и отлаживается.

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

6. Каждый модуль имеет одну точку входа и одну точку выхода.

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

8. Модули могут объединяться в более крупные модули без знания особенностей их внутреннего содержания.

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

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

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

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

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

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

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

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

Рис. 1. Схема модуляризации

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

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

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

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

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

4. Схема взаимосвязей модулей определяет потоки управления в структурной программе.

Между модулями существуют отношения активизации, т.е. один модуль может вызывать другой. Так, если модуль А вызывает модуль В, то это означает, что управление передается от модуля А к модулю В. Модуль А называется вызывающим или родительским, а модуль В - вызываемым, или дочерним. Иногда их называют соответственно “отец - сын”. В структурной программе существуют следующие правила для потока управления:

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

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

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

4. Управление программой должно входить в модуль в точку входа и покидать модуль в точке выхода.

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

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

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

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

Оценка качества модульной программы

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

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

Три фактора оказывают влияние на сцепление модулей:

1. Число элементов данных, передаваемых между ними (чем больше передается данных, тем сильнее сцепление).

2. Количество управляющих данных, передаваемых между модулями.

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

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

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

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

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

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ

Зачем нужно ООП

ООП как полностью разработанная концепция программирования возникла не вдруг. Идея использования программных «объектов» развивалась в течение многих лет разными коллективами. Были созданы системы исследовательского назначения, убедительно демонстрирующие такие достоинства ООП, как многозначность использования и расширяемость программных кодов. Однако при всей привлекательности, ряд особенностей ООП препятствовал его широкому внедрению. Системы ООП обычно отличаются громоздкостью и невысоким быстродействием, что в большей мере определялось чисто техническими проблемами. Также особенностью таких систем было использование специализированных языков, которые сильно отличаются от популярных FORTRAN, PASCAL и С.

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

Объектно-ориентированный подход

Если Вы зададите вопрос: `Что такое ООП?' то в ответ услышите много определений, и во всех из них этот термин употребляется не в его точном смысле. Даже в тех случаях, когда вопрос касается не конкретных продуктов или инструментов, акцент опять-таки будет поставлен по-разному, в зависимости от того, какие именно стороны ООП собеседник считает наиболее полезными и интересными. Получается, что каждый пользователь дает свое собственное определение, в зависимости от конкретной задачи решаемой им.

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

Теперь подойдем к определению ООП:

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ - это способ программирования, обеспечивающий модульность программ за счет разделения памяти на области, содержащие данные и процедуры. Области могут использоваться в качестве образцов, с которых по требованию могут делаться копии.

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

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

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

Отметим, что и ООП имеет метафоры, к ним можно отнести ` наследование ', ` классы ', ` передача сообщений '.

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

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

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

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

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

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

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

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

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

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

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

Элементы концептуальной базы ООП

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

· абстрагирование;

· инкапсуляция;

· модульность;

· иерархия.

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

· типизация;

· параллелизм;

· сохраняемость.

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

Абстрагирование

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

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

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

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

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

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

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


Подобные документы

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

    реферат [40,0 K], добавлен 01.04.2010

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

    курсовая работа [698,3 K], добавлен 09.12.2013

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

    презентация [1,8 M], добавлен 05.11.2016

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

    контрольная работа [51,7 K], добавлен 22.01.2013

  • Появление первых вычислительных машин и возникновение "стихийного" программирования. Структурный подход к декомпозиции сложных систем. Развитие модульного и объектно-ориентированного программирования. Особенности компонентного подхода и CASE-технологий.

    презентация [1,5 M], добавлен 14.10.2013

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

    презентация [74,8 K], добавлен 14.10.2013

  • Понятие алгоритма и его характеристики как основного элемента программирования. Формы представления алгоритмов, основные алгоритмические структуры. Структурное и событийно-ориентированное программирование. Объектно-ориентированное программирование.

    реферат [86,0 K], добавлен 17.07.2008

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

    курсовая работа [2,6 M], добавлен 17.11.2014

  • Приемы и правила объектно-ориентированного программирования с использованием языка С++. Общие принципы разработки объектно-ориентированных программ. Основные конструкции языка С++. Разработка различных программ для Windows с использованием WIN32 API.

    учебное пособие [1,6 M], добавлен 28.12.2013

  • Объектно-ориентированный язык программирования: общая характеристика и свойства. Базовый и производный классы, конструкторы производного класса. Конструкторы и неопределенность при множественном наследовании. Роль наследования при разработке программ.

    курсовая работа [688,3 K], добавлен 23.12.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.