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

Большинство авторов публикаций, посвященных структурам и ор-

ганизации данных, делают основной акцент на том, что знание

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

максимально эффективным образом - с точки зрения минимизации зат-

рат как памяти, так и процессорного времени. Другим не менее, а

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

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

вания сложного программного изделия. Современные промышлено вы-

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

которых исчисляется тысячами и миллионами строк кода, а трудоем-

кость разработки - сотнями человеко-лет. Естественно, что разра-

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

должно быть представлено в виде какой-то структуры - составных

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

дает возможность на каждом этапе разработки сосредоточить внима-

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

реализацию разных его частей разным исполнителям.

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

применение подхода, основанного на структуризации алгоритмов и

известного, как "нисходящее" проектирование или "программирование

сверху вниз", или подхода, основанного на структуризации данных и

известного, как "восходящее" проектирование или "программирование

снизу вверх".

В первом случае структурируют прежде всего действия, которые

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

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

кольких подзадач меньшего объема. Таким образом, модуль самого

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

чается достаточно простым и обеспечивает только последователь-

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

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

тем каждая подзадача в свою очередь подвергается декомпозиции по

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

тех пор, пока на очередном уровне декомпозиции получают подзада-

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

чае декомпозиция может быть доведена до того, что подзадачи само-

го нижнего уровня могут быть решены элементарными инструменталь-

ными средствами (например, одним оператором выбранного языка

программирования).

Другой подход к структуризации основывается на данных. Прог-

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

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

что программирование - это обработка данных. В программах можно

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

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

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

ходные данные, а какими средствами это обеспечивается - его не

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

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

ные средства программирования предоставляют набор базовых (прос-

тых, примитивных) типов данных и операции над ними. Интегрируя

базовые типы, создаются более сложные типы данных и определяются

новые операции над сложными типами. Можно здесь провести аналогию

со строительными работами: базовые типы - "кирпичики", из которых

создаются сложные типы - "строительные блоки". Полученные на пер-

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

базового набора для следующего шага, результатом которого будут

еще более сложные конструкции данных и еще более мощные операции

над ними и т.д. В идеале последний шаг композиции дает типы дан-

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

над этими типами реализуют в полном объеме задачу проекта.

Программисты, поверхностно понимающие структурное программи-

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

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

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

чем, с постоянной коррекцией структур алгоритмов по результатам

разработки структур данных и наоборот.

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

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

ее состоит в том, что сконструированный новый тип данных - "стро-

ительный блок" - оформляется таким образом, что его внутренняя

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

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

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

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

этого. Новый тип данных представляется для него в виде "черного

ящика" для которого известны входы и выходы, но содержимое - не-

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

Инкапсуляция чрезвычайно полезна и как средство преодоления

сложности, и как средство защиты от ошибок. Первая цель достига-

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

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

поля зрения программиста-пользователя. Вторая цель достигается

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

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

вероятность ошибок.

Современные языки программирования блочного типа (PASCAL, C)

обладают достаточно развитыми возможностями построения программ с

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

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

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

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

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

ней структурой - методы работы с объектами. При этом в значитель-

ной степени меняется и сама концепция программирования. Програм-

мист, оперирующий объектами, указывает в программе ЧТО нужно

сделать с объектом, а не КАК это надо делать.

Технология баз данных развивалась параллельно с технологией

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

этим, а отчасти и объективными различиями в природе задач, решае-

мых системами управления базами данных (СУБД) и системами прог-

раммирования, вызваны некоторые терминологические и понятийные

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

в СУБД является понятие модели данных, в основном тождественное

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

структура данных в СУБД не рассматривается вообще. Но сами СУБД

являются программными пакетами, выполняющими отображение физичес-

кой структуры в логическую (в модель данных). Для реализации этих

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

ботчики СУБД, следовательно, имеют дело со структурами данных в

терминах систем программирования. Для пользователя же внутренняя

структура СУБД и физическая структура данных совершенно прозрач-

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

логического уровня.