Primus Inter Pares

Методологии разработки БПК
(02 March 2010)

Содержание

Исторические заметки
Цели структурного программирования
Основные принципы структурной методологии
Модульное программирование
Стандарты структурного программировани

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

ИСТОРИЧЕСКИЕ ЗАМЕТКИ

К началу 70-х годов уже было очевидно, что программные проекты стали слишком сложными для успешного проектирования, кодирования и отладки в приемлемые сроки. Кроме того, программисты, решающие сложные задачи, столкнулись с проблемой разрастания количества и размера программ до такой степени, что дальнейший процесс разработки становился практически неуправляемым, и никто из разработчиков не мог с уверенностью сказать, что созданный программный продукт всегда выполняет то, что требуется, и что он не выполняет ничего такого, что не требуется. Таким образом, стала проблема коренного изменения подходов к созданию больших программных комплексов.
Исходя из этих проблем, лучшими программистами 70-х годов (Дейкстра, Вирт, Дал, Хоар, Йордан, Константин, Майерс и другие) были разработаны строгие правила ведения проектов, которые получили название структурной методологии.
Важным этапом в становлении новых методологий стали международные конференции по программированию в 1968 и 1969 годах. На второй из них Эдсгер Дейкстра (Dijkstra) впервые использовал термин "структурное программирование" и предложил принципиально новый способ создания программ. Он рассматривал программу как совокупность абстрактных иерархических уровней, которые позволяли четко структурировать программу, что улучшило ее понимаемость программистами, выполнять доказательства ее корректности и тем самым повышать надежность функционирования программы и сокращать сроки ее разработки.
Еще одним толчком к изменению способа программистского мышления стало опубликованное письмо Дейкстры редактору одного из Научных издательств, которое было озаглавлено "Оператор GOTO нужно считать вредным". Это письмо вызвало острую полемику среди программистов того времени, но в итоге победило все-таки структурное мышление, которое кроме Дейкстры активно поддерживали профессор Цюрихского технического университета Вирт (Wirth) и профессор Оксфордского Университета Хоар (Hoare). Одним из результатов полемики было доказательство того, что любая программа может быть написана используя только простую последовательность операторов, итеративную конструкцию типа while и конструкцию выбора case, а оператор goto не является необходимой управляющей конструкцией в структурном программировании. К сожалению, споры об операторе goto имели один отрицательный "побочный эффект" - довольно часто программирование без goto стало отождествляться со всем структурным программированием. Однако цели структурного программирования намного глобальнее и серьезнее.

ЦЕЛИ СТРУКТУРНОГО ПРОГРАММИРОВАНИЯ

Обеспечить дисциплину программирования
Обеспечение дисциплины программирования в процессе создания программных комплексов является основной целью структурного программирования и главным фактором достижения остальных его целей. Дейкстра дал следующее определение: «Структурное программирование – это дисциплина, которую программист навязывает сам себе».
Улучшать читабельность программы
Читабельность улучшается, если придерживаться следующих правил:
•избегать использования языковых конструкций с неочевидной семантикой;
•стремиться к локализации действия управляющих конструкций и использования структур данных;
•разрабатывать программу так, чтобы ее можно было читать от начала до конца без управляющих переходов на другую страницу.
Повышать эффективность программы
Повышения эффективности можно достигнуть, если выполнять структурирование программы, разбивая ее на модули так, чтобы можно было легко находить и корректировать ошибки, а также чтобы текст любого модуля с целью увеличения эффективности можно было переделать независимо от других.
Повышать надежность программы
Высокой надежности функционирования программы можно достичь, если она будет легко поддаваться сквозному тестированию и не создаст проблем для организации процесса отладки. Это обеспечивается хорошим структурированием программы при разбивке ее на модули и выполнением правил написания читабельных программ.
Уменьшать время и стоимость программной разработки
Уменьшение стоимости и времени разработки программных комплексов происходит в том случае, если каждый программист команды разработчиков становится способным писать и отлаживать большее количество программного кода, чем раньше. То есть, когда повышается производительность труда программиста. Соблюдение правил структурного программирования позволяет этого достигнуть.

ОСНОВНЫЕ ПРИНЦИПЫ СТРУКТУРНОЙ МЕТОДОЛОГИИ

Принцип абстракции
Абстракция позволяет разработчику вообразить требуемое решение проблемы без сиюминутного учета множества деталей. Используя принцип абстракции, разработчик может рассматривать программу по уровням. Верхний уровень показывает нам большую абстракцию, упрощает взгляд на проект, в то время как нижний уровень показывает мелкие детали реализации.
На принципе абстракции основываются многие структурные методы, например, восходящая и нисходящая стратегии программирования.
Принцип формальности
Вторым фундаментальным принципом структурного подхода является принцип формальности. Слово "формальность" предполагает строгий методический подход.
Принцип формальности является базой для превращения программирования из импровизации в инженерную дисциплину.
Кроме того, этот принцип дает основания для доказательства правильности программ, так как позволяет изучать программы (алгоритмы) как математические объекты.
Введению формальности в некоторый процесс, технический или не технический, часто сопротивляются на основании того, что она подавляет творчество. Однако структурный подход использует формальность для придания процессу творчества определенной дисциплины и строгости, что позволяет ускорять принятие решений и избегать множества ошибок. Формальность является положительным и мощным способом соединения искусства и инженерных аспектов программирования.
Принцип "разделяй и властвуй"
Принцип "разделяй и властвуй" известен со времен Юлия Цезаря и является методом решения трудных проблем путем разделения проблемы на множество мелких независимых, которые легче пони-мать и решать.
В ракурсе применения к разработке программного обеспечения этот принцип означает разделение программы на отдельные фрагмент (модули), которые просты по управлению и допускают независимую отладку и тестирование. Он позволяет разработчику программ спокойно работать над отдельной частью большой системы, не заботясь об огромном количестве деталей, охватывающих всю систему.
Принцип иерархического упорядочения
Принцип иерархического упорядочения тесно связан с принципом "разделяй и властвуй". Структура разбиения на части не менее важна, чем сам факт такого разделения. Принцип иерархического упорядочения с успехом используется во всех сферах жизнедеятельности человека и помогает решать сложные проблемы управления в системах, включающих множество частей.
В применении к программированию этот принцип выдвигает требование иерархического структурирования взаимосвязей между модулями программного комплекса, что облегчает достижение рассмотренных выше целей структурного программирования.

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

Основным принципом модульного программирования является принцип "разделяй и властвуй". Модульное программирование — это организация программы как совокупности небольших независимых блоков, называемых модулями, структура и поведение которых подчиняются определенным правилам.
Заметим, что нужно различать использование слова "модуль", когда имеется в виду синтаксическая конструкция языков программирования (unit в Turbo Pascal), и когда имеется в виду единица дробления большой программы на отдельные блоки (которые могут быть реализованы и в виде процедур, и в виде функций).
Использование модульного программирования позволяет упростить тестирование программы и обнаружение ошибок. Аппаратно-зависимые подзадачи могут быть строго отделены от других подзадач, что улучшает мобильность создаваемых программ.
Упрощается процесс повышения эффективности программ, так как критичные по времени модули могут многократно переделываться независимо от других. Кроме того, модульные программы значительно легче понимать, а модули могут использоваться как строительные блоки в других программах.
Термин "модуль" в программировании начал использоваться в связи с внедрением модульных принципов при создании программ. В 70-х годах под модулем понимали какую-либо процедуру или функцию, написанную в соответствии с определенными правилами. Например: «Модуль должен быть простым, замкнутым (независимым), обозримым (от 50 до 100 строк), реализующим только одну функцию задачи, имеющим только одну входную и только одну выходную точку". Однако общепризнанных требований не было и модулем очень часто называли любую процедуру размером до 50 строк.
Первым основные свойства программного модуля более-менее четко сформулировал Парнас (Parnas): "Для написания одного модуля должно быть достаточно минимальных знаний о тексте другого". Таким образом, в соответствии с этим определением, модулем могла быть любая отдельная процедура (функция) как самого нижнего уровня иерархии (уровня реализации), так и самого верхнего уровня, на котором происходят только вызовы других процедур-модулей.
Таким образом, Парнас первым выдвинул концепцию скрытия информации (information hiding) в программировании. Однако существующие в языках 70-х годов только такие синтаксические конструкции, как процедура и функция, не могли обеспечить надежного скрытия информации, поскольку подвержены влиянию глобальных переменных, поведение которых в сложных программах зачастую бывает трудно предсказуемым.
Решить эту проблему можно было только разработав новую синтаксическую конструкцию, которая не подвержена влиянию глобальных переменных.
Такая конструкция была создана и названа модулем. Изначально предполагалось, что при реализации сложных программных комплексов модуль должен использоваться наравне с процедурами и функциями как конструкция, объединяющая и надежно скрывающая детали реализации определенной подзадачи.
Таким образом, количество модулей в комплексе должно определяться декомпозицией поставленной задачи на независимые подзадачи. В предельном случае модуль может использоваться даже для заключения в него всего лишь одной процедуры, если необходимо, чтобы выполняемое ею локальное действие было гарантировано независимым от влияния других частей программы при любых изменениях и коррекциях. Такое использование модуля характерно для класса задач реального времени, в которых критерий надежности и предсказуемости поведения программы является ключевым.
Впервые специализированная синтаксическая конструкция модуля была предложена Н.Виртом в 1975 г. и включена в его новый язык Modula. В этом же году была сделана опытная реализация языка Modula. После некоторой переработки этот новый язык был окончательно реализован в 1977 г. и получил название Modula-2. Впоследствии, аналогичные конструкции, с некоторыми отличиями, были включены и в другие языки программирования: Pascal Plus (Уэлш и Бастард, 1979 г.), Ada (1980) Turbo Pascal версии 4.0.

Форма модульной программы

Придание иерархической структуре модульной программы хорошей формы позволяет улучшить процесс ее разработки.
Число модулей, которые вызываются каким-либо модулем, и число модулей, которые его вызывают, оказывают влияние на сложность программы. Йодан (Yourdon) назвал число модулей, вызываемых из данного модуля, размахом или шириной управления модулями. Наряду с большим размером модуля, очень маленькая или очень большая ширина управления является признаком плохой схемы разбивки на модули. В общем случае, ширина управления модуля не должна превышать 10-ти. Это число связано с "магическим" числом 7, которое базируется на положениях психологии и, в особенности, на теории "кусков" ("chunking") информации. Кратковременная память человека имеет ограниченные способности сохранения "кусков" информации. Психологические эксперименты показали, что способность нашей кратковременной памяти находится в пределах 5-9 "кусков" (в среднем — 7). Она может одновременно оперировать около 7 "кусками" информации. Когда человек превышает этот предел, он более склонен к ошибкам.
Реорганизация информации с разбивкой на подходящие части является важным действием для эффективного использования кратковременной памяти человека и для улучшения понимаемости материала. Люди во многих жизненных ситуациях делают такую реорганизацию бессознательно. Однако программист может сам себе помочь, сознательно допуская ширины управления модулями, которая превышает число 7.

СТАНДАРТЫ СТРУКТУРНОГО ПРОГРАММИРОВАНИЯ

1. Программа должна разделяться на независимые части, называемые модулями.
2. Модуль — это независимый блок, код которого физически и логически отделен от кода других модулей. Модуль выполняет только одну логическую функцию. Размер модуля не должен превышать 100 операторов. Модуль имеет одну входную и одну выходную точку. Взаимосвязи между модулями устанавливаются по иерархической структуре. Каждый модуль должен начинаться с комментария, объясняющего его назначение, назначение переменных, передаваемых в модуль и из него, модулей, которые его вызывают, и модулей, которые вызываются из него.
8.Избегать ненужных меток и использовать оператор goto только для переходов на входную или выходную точку модуля, или вообще не использовать.
9. Идентификаторы всех переменных и модулей должны быть смысловыми.
10.Родственные группы идентификаторов должны начинаться с одинакового префикса.
11. Использовать только стандартные управляющие конструкции (выбор, цикл, выход, блок).
12.В одной строке записывать не более одного оператора. Если для записи оператора требуется больше, чем одна строка, то все последующие строки записываются с отступами.
13. Не допускать вложенности операторов if более 3-х уровней.
14.Избегать использования языковых конструкций с неочевидной семантикой и программистских "трюков". Например, в языке С вполне допустима следующая программа, которая работает противоположно тому, что должно было бы быть на первый взгляд:

#include <stdio.h>
main()
{
if (3<2<1) printf(“Вот это ерунда!!!”);
else printf(“А Паскаль такого не позволяет!”);
}

Интересные ссылки по теме:


Автор: softmind.bos.ru
Использованы материалы книги
:
Программирование в среде Turbo Pascal
Авторы: А.И.Марченко, Л.М.Марченко

 
 
Р Е К Л А М А
        (C) softmind.bos.ru. 2009-2010 г.