© А.И. Легалов

Упадок других парадигм

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

Упадок структурного программирования

Самый ощутимый удар был нанесен по структурному программированию [Дал75] (в то время являющемуся наиболее популярным методом разработки программ). Изначально оно рассматривалось как разработка кода, основанного на функциональных зависимостях решаемой задачи. При создании кода использовались удобочитаемые императивные конструкции [Хендерсон]. Отличаясь в первоначальном варианте от предшествующих методов лишь запретом на использование оператора безусловного перехода, оно в дальнейшем дало толчок разнообразным подходам, сочетающим функциональную декомпозицию с декомпозицией данных и использованием абстрактных типов данных. Появились отдельные методики разработки структур данных и средств управления программой, а также методы обеспечивающие формирования кода по разработанным структурам данных. Ясная логическая структура управляющих примитивов привела к созданию методов доказательства правильности программ [Дейкстра78]. Часть достигнутых результатов была использована в методах структурного анализа и проектирования, применяемых до сих пор.

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

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

Упадок функционального программирования

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

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

Упадок параллельного программирования

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

Такое соответствие позволило в 80-е годы разработать и успешно применять разнообразные языки параллельного программирования на основе уже существующих процедурных и функциональных языков. Причем, возможности распараллеливания никак не влияли на логику управления вычислениями, зависящую от структур данных. Параллелизм только позволял ускорить выполнение операций, не зависящих информационно друг от друга. Можно также отметить, что в это же время получила широкое развитие теория параллельного программирования. Были разработаны разнообразные модели параллельных вычислений, поддерживающие распараллеливание от уровня процессов-программ до уровня команд [Хоар]. Именно теория позволила создать нетрадиционные языки параллельного программирования, ряд из которых нашли практическое применение [Алгоритмы].

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

В настоящее время языки параллельного программирования практически перестали использоваться для разработки больших программ. Как и в ранее описанных случаях, их сгубила процедурность. Естественно, что современные ОО языки поддерживают параллельную обработку данных, которая осуществляется либо через системные вызовы ОС, либо непосредственно встроена в ОО язык (например, в Java [Нортон]). Эта поддержка не реализует какую-либо оригинальную модель вычислений. Она просто воспроизводит возможности ОС. Последние же, обычно, поддерживают те возможности, которые предоставляются аппаратурой. Поэтому, можно сказать, что ООП затормозило практическое развитие методов параллельной обработки данных.