SoftCraft
разноликое программирование

Отправная точка
Программирование
Windows API
Автоматы
Нейроинформатика
Парадигмы
Параллелизм
Проектирование
Теория
Техника кодирования
Трансляторы
Прочие вопросы

Разное

Беллетристика
Брюзжалки
Цели и задачи
Об авторе


Процессы, которые мы потеряли


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

2001 г.

Содержание


Ссылки на используемые источники информации

Итоги экспансии объектно-ориентированной парадигмы

На дворе третье тысячелетие. По десктопам, серверам и мэйнфреймам победоносно шествует объектно-ориентированное программирование (в простонародье ООП). За какие-то 15 лет оно воплотилось в господствующую религию, подчинившую умы миллионов программистов. Популярность ООП и его доминирование уже ни у кого не вызывает сомнений. В настоящее время оно фактически стало стандартом де-факто. С использованием объектно-ориентированной методологии (ООМ) осуществляется разработка огромного числа программных проектов, а ООП является основным инструментом для построения кода. Повышение эффективности кодирования осуществляется путем автоматизации процессов объектно-ориентированного проектирования за счет применения соответствующих CASE средств. Наиболее известным инструментом проектирования является Rational Rose [Буч98]. Языки программирования, методологии, приложения, операционные системы, базы данных... Куда не плюнь - кругом "объективная реальность". Вот только основные ее достижения.

Объектно-ориентированные языки программирования

Объектно-ориентированные расширения, в той или иной форме, были добавлены в ряд ранее известных языков программирования, что продлило их существование. Среди них наиболее известны следующие "гермафродиты": С++ (расширение C) [Страуструп], Delphi (расширение Pascal) [Гофман], MS Visual Basic (расширение Basic) [Райтингер]. Они потеснили на рынке средств разработки такого однополого корифея ООП, как Smalltalk [Goldberg]. В каждом из этих языков объектно-ориентированные расширения были проведены в различном объеме. Наиболее продвинутым в этом направлении оказался C++. Популярность C у программистов, лидерство во времени плюс качество введенных конструкций способствовали тому, что C++ стал одним из наиболее известных языков объектно-ориентированного программирования. Delphi и VB также занимают достаточно устойчивые позиции. Во многом это связано не с их объектной ориентированностью, а тесной интеграцией с методами быстрой разработки, базами данных и компонентными технологиями, что позволяет достаточно быстро строить приложения средней сложности. Такие инструменты существуют и для С++ (C++ Builder [Архангельский]). Однако, ООМ считает их использование в разработке больших программных систем неэффективным [Васкевич]. Следует также отметить язык программирования Оберон-2 [MoessenboeckWirth], разработанный под руководством Н. Вирта. Данный язык обладает простой структурой, компактен. Он сохраняет понятие типа, используемое в процедурном подходе. Для придания языку свойств объектного, предложен механизм связанных процедур.

Последовавшая затем "кастрация" механизмов процедурного порождения программ привела к появлению новых, чисто объектных (как и Smalltalk) языков, тесно интегрированных с современной информационной средой. Наиболее популярным из них оказался язык Java [Нортон], ориентированный на кросс платформенную виртуальную машину, адаптированную к функционированию в среде Internet. Поддерживаемая агрессивной маркетинговой политикой, ОО Java-технология заняла на рынке средств разработки одно из ведущих мест. А последним "писком" является C# [Hejlsberg] - объектно-ориентированный кастрат от Microsoft в пику Java. Фрагмент генеалогического дерева, отражающего особенности развития объектно-ориентированных языков, представлен на рис. 1.

Объектно-ориентированная эпидемия коснулась и языков сценариев, изначально ориентированных на написание небольших скриптов и не нуждающихся в поддержке технологий, связанных с разработкой очень больших программных систем. ОО "прибамбасы" существуют в Java Script [Дарнел], их также предлагается ввести и в VB Script [Хиллер]. Как всегда, на высоте оказался идиоматический Perl [Маслов], который и без того включает много наворотов.

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

Объектная модель

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

"Все могло бы быть совсем не так..."

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

Но, процедура - это частный случай процесса, который, наряду с выполнением операций может переходить в состояние ожидания. Сравним жизненные циклы класса и элементарного процесса (рис. 2). Их практическая эквивалентность говорит о том, что процесс может делать все то же, что и класс. А уж сымитировать с его помощью модель класса - вообще нет проблем. При этом процесс, в общем случае, обеспечивает такую динамику поведения, которая не "снилась" ни одному другому программному объекту (достаточно почитать классиков [Хоар, Языки]).

Примечание. Впервые тема эквивалентности классов и процессов обсуждалась нами примерно в 1991 году после ознакомления с Turbo C++ v.1.0. Это происходило в Институте проблем вычислительной техники АН СССР (Ярославль). Но тогда нас профессионально интересовали архитектуры параллельных вычислительных систем и языки параллельного программирования. Поэтому, мы быстро отошли от этих рассуждений и не обратили внимания на наступление новой эры. Интересна история появления Turbo C++ v.1.0. Это единственная версия компилятора, которую я ставил без дистрибутива. Легенда гласит, что ребята из Borland привезли компилятор на какую-то выставку. В обеденный перерыв они отсоединили от компьютера клавиатуру и унесли с собой в столовую. Думали, наверное, что в СССР PC-клавиатуры не найдется! А клавиатура нашлась. Поэтому компилятор быстро упаковали, а потом и распространили (продаю, за что купил:). А.Л.

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

Пример кода на C++

Пример кода на P++

// Абстрактный класс, описывающий
// обобщенную геометрическую фигуру.
// Базовый для классов прочих фигур
class shape {
public:
 virtual void In()=0; // ввод
 virtual void Out()=0; // вывод
 // Вычисление площади фигуры
 virtual double Area() = 0; 
};

// Класс - прямоугольник
class rectangle: public shape
{
 int x, y; // ширина, высота
public:
 // Переопределяем интерфейс класса
 void In();
 void Out();
 double Area();
 // Конструкторы класса
 rectangle(int _x, int _y);
 rectangle() {}
};

// Методы класса - прямоугольника
...
// Вычисление площади прямоугольника
double rectangle::Area() {
 // возврат значения
 // переход в пассивное состояние
 return x * y;
}

...

// Использование классов
void main()
{
  // автоматическое создание класса
 rectangle r;
 // использование методов класса
 r.In();
 double a = r.Area();
 // динамическое создание класса
 shape *s new rectangle(3, 4);
   ...
 // удаление динамического класса
 delete s;
}
// автоматически созданный
// класс удалился
// Абстрактный процесс, описывающий
// обобщенную геометрическую фигуру.
// Базовый для процессов прочих фигур
process shape {
public:
 virtual void In()=0; // ввод
 virtual void Out()=0;// вывод
 // Вычисление площади фигуры
 virtual double Area() = 0;
};

// Процесс - прямоугольник
process rectangle: public shape
{
 int x, y; // ширина, высота
public:
 // Переопределяем интерфейс процесса
 void In();
 void Out();
 double Area();
 // Конструкторы процесса
 rectangle(int _x, int _y);
 rectangle() {} 
};

// Методы процесса - прямоугольника
...
// Вычисление площади прямоугольника
double rectangle::Area() {
 // возврат значения
 // переход в состояние ожидания
 wait x * y;
}

...

// Использование процессов
void main()
{
 // автоматический запуск процесса
 rectangle r;
 // использование методов процесса
 r.In();
 double a = r.Area();
 // запуск динамического процесса
 shape *s new rectangle(3, 4);
  ...
 // завершение динамического процесса
 delete s;
}
// автоматически запущенный 
// процесс завершился

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

Начнем с того, что создание и поддержка процессов осуществляется достаточно давно и различными способами. Практически все операционные системы в настоящее время поддерживают мультипрограммный и мультипроцессорный режимы, как на уровне процессов, так и на уровне ветвей (потоков, нитей). Поэтому, вряд ли могут возникнуть проблемы по порождению процессов только из-за того, что они описаны в стиле, напоминающем объектный. Более того, поддержка процессов и задач осуществляется даже на аппаратном уровне практически во всех современных микропроцессорах. Всем нам известные 32-х разрядные процессоры для ПК фирмы Intel имеют такую возможность с момента своего появления [Шагурин]. Глобальность этого механизма, сочетание виртуальной и страничной адресации позволяют использовать все возможности современных операционных систем.

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

Традиционно процессы организованы так, что обеспечивают запуск из одной точки с одним вариантом начальных значений. Альтернативные ветви, выходящие из точки ожидания обычно порождаются путем выполнения условных операторов. Поэтому, могут появиться сомнения по поводу наличия нескольких различных точек запуска процессов, эквивалентных конструкторам класса. Червь сомнения может глодать нас и при обсуждении возможности наличия у процесса внутренних методов, отвечающих за отдельные ветви, эквивалентные методам класса. Перефразируя одну печально известную фразу можно сказать: "Оставь сомнения всяк, в процесс входящий"! Множество точек входов и ранее встречалось, даже в процедурах. Достаточно вспомнить PL/1 [Фролов]. А реализация оболочки процесса может быть такой же, как и у компонента используемого в COM [Роджерсон]. Эта двоичная оболочка, фиксирующая только указатель на таблицу функций, позволяет интерпретировать себя как угодно. Кстати, большинство реализаций класса используют точно такую же структуру. Поэтому, вряд ли у процессов возникнут проблемы с инкапсуляцией, полиморфизмом и наследованием.

Итак, технических проблем вроде бы не видно. Но остаются морально-этические. Спрашивается: "А зачем все это надо"? Разве не достаточно, для полного счастья, объектно-ориентированного подхода? Конечно, можно было бы сказать, что это моя месть за процедурное и параллельное программирование. Однако вряд ли такой аргумент можно считать убедительным. Скорее всего, это попытка показать, что после объединения процедур и данных в единую оболочку не существует однозначного толкования и интерпретации возникшего винегрета. На уровне реализации это может объект, а может - процесс. Поэтому, не стоит серьезно относиться и к словам Гради Буча о том, что объектная декомпозиция имеет несколько чрезвычайно важных преимуществ перед алгоритмической. И алгоритмическая декомпозиция позволяет учитывать модель состояний, если опирается на декомпозицию процессов. И в перспективе она может использовать инкапсуляцию, наследование и полиморфизм. Поэтому, вряд ли стоит ставить крест на структурном анализе и проектировании, начинающемся с описания бизнес процессов.

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

Методологические выкрутасы

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

Куда это я клоню? А вот куда. Описывая основные достоинства ООМ Гради Буч [Буч98] совершенно серьезно говорит, что: "Объектная модель позволяет в полной мере использовать выразительные возможности объектных и объектно-ориентированных языков программирования". Как будто построение объектной модели происходило не на основе этих самых языков! Ведь любая методология разрабатывается с использованием уже накопленных в предметной области эмпирических фактов и практических результатов, коими, в данном случае, и являлись существующие языки программирования. Ведь до появления ООМ прошел не один десяток лет, если плясать от Симулы-67 [Дал69]. Только идиоты, политики и менеджеры могут создавать методологии, которые не используют выразительные возможности языков. Вряд ли можно отнести Буча к первым двум категориям. Это голова и гигант мысли в одном флаконе! Следовательно, он немного перестарался, чтобы раскрутить свои методы. Хотя, и политики в программировании более чем достаточно [Йордон].

Но, вместе с тем, я имею наглость утверждать, что методологическая надстройка - это такое надуманное творение, которое легко можно приспособить и к другим, альтернативным, идеям (политики постоянно подтверждает это на практике:). В частности, что нам мешает выстроить на процессах парадигму программирования, аналогичную объектно-ориентированной? Достаточно заменить "объект" на "процесс", чтобы прослыть новым методологом. И сейчас правой рукой я набираю на клавиатуре этот текст, а левой, в это время, судорожно правлю экземпляр книги Гради Буча [Буч98]. Надо спешить. И пусть меня попробуют обвинить в плагиате! Ведь сам Буч написал: "Однако, мы не можем сконструировать сложную систему двумя способами, тем более, что эти способы по сути ортогональны". Значит, новая методология будет другой, хоть и написана теми же словами. Я прекрасно осознаю все зыбкость этих "методологических" утверждений, но не могу удержаться от неожиданно наступившего словоизлияния.

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

Отчуждение клиента от собственности

ОО подход породил множество постулатов и догм, определяющих правильный стиль программирования. Со временем они перекочевали в различные книжки. Ряд зафиксированных приемов оказались связанными со спецификой конкретных языков программирования [Голуб, Мейерс2000-1, Мейерс2000-2, Элджер]. Другие были заявлены как универсальные и обосновались в "приемах объектно-ориентированного проектирования" [Гамма]. Я не отрицаю полезность накопленного эмпирического опыта и с удовольствием использую его в своей практике. Но, вместе с тем, создается впечатление, что мы пользуемся не той системой отсчета. Что-то напоминает геоцентрическую систему Птолемея, которая поставила землю в центр вселенной. Для простейших расчетов все идет нормально. Но как только переходим к более сложным и точным расчетам, каждая планета начинает двигаться по каким-то непонятным, дополнительным окружностям. И без уточняющих правил, исключений, измерительных инструментов, а также шаманских ритуальных плясок не обойтись. Я не думаю, что в мгновение ока поставлю в центр нашей системы солнце. Скорее всего, у меня на этом месте расположится Марс. Однако, ряд суждений хотелось бы сделать.

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

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

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

Перед тем, как уйти

Таким образом, еще в середине 80-х годов развитие программирование могло бы пойти альтернативным направлением, открывающим не меньше возможностей, чем те, которые используются сейчас. В очередной раз можно сказать, что для этого были все предпосылки. И вновь встает извечный русский вопрос: Кто виноват? Почему же такие возможности построения процессов были упущены и не реализованы в свое время? Почему мы потеряли ПОП? Я вижу единственный, истинно российский, ответ: в свое время Дейкстре, Хоару и Бучу не удалось собраться вместе и, по старой русской традиции, "сообразить" на троих. Все просто. Каждый идет своей дорогой, собирая те знания, которые его больше интересуют, и почти не смотрит на соседей. Что рядом творится - мало кому интересно. Хотя, может быть еще не все потеряно... Ведь мы такие!.. Сами себя и везде считаем самыми лучшими программистами в мире. Поэтому, раз плюнем - и новая технология в кармане. Возможно, что ПОП вполне может явиться продолжением ООП...

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

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

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

И уходя

Я подставился и всем своим телом ощущаю кипение возмущенного разума. Возможно, у кого-то возникнет желание дать мне в зубы :-F, сломать о мою голову монитор ]:-(, выдрать из моей "клавы" закрывающуюся круглую скобку, шоб бовше не уыбався :-#. Поэтому на прощание расскажу еще одну притчу из своей бытности студентом.

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

В 1992 году окончательно развалился проект параллельной вычислительной системы, в работе над котором я принимал участие. В период безделья я набросал объектно-ориентированный параллельный язык, который попытался предложить одной из оборонных фирм, наивно полагая, что они держатся на плаву. Но развал коснулся всех. Если кому-то интересно узнать, что было в этой жалкой попытке, можете качнуть предлагаемый архив (в формате MS DOS). Там, кстати, я отталкивался от взаимодействия последовательных процессов [Хоар] и пытался заменить его взаимодействием последовательных объектов. Сейчас все поменялось с точностью до наоборот. Процессы вместо объектов. Все-таки, до чего разнолико программирование!

А теперь спросите меня: "Почему такой серьезный материал написан в таком легкомысленном стиле"? Я отвечу: это - провокация. Провокация более широкого обсуждения возможных путей развития технологий программирования. Ведь зачем-то я упоминал в начале третье тысячелетие...

Поэтому, закончить хотелось бы бессмертными словами классиков, помогавших мне в написании этого материала: