Использование объектно-ориентированной методологии не ограничено каким-либо одним языком программирования - она применима к широкому спектру объектных и объектно-ориентированных языков. Наряду с анализом и проектированием, несомненно важны особенности конкретного языка программирования, поскольку в конечном счете наши конструкции должны быть выражены на каком-то языке. Как отметил Вульф, язык программирования служит трем целям:
• это инструмент проектирования;
• это средство человеческого восприятия;
• это средство управления компьютером [1].
Данное приложение предназначено для читателей, не знакомых с языками программирования, упоминавшимися в этой книге. Мы приводим сводное описание наиболее важных из них, а также примеры, позволяющие сопоставить синтаксис, семантику и идиомы двух самых интересных - C++ и Smalltalk.
В настоящее время насчитывается более двух тысяч языков программирования высокого уровня. Большинство этих языков возникло исходя из конкретных требований некоторой предметной области. Каждый новый язык позволял переходить ко все более и более сложным задачам. На каждом новом приложении разработчики языков что-то открывали для себя и изменяли свои представления о существенном и несущественном в языке. На развитие языков программирования значительное влияние оказали достижения теории вычислении, которые привели к формальному пониманию семантики операторов, модулей, абстрактных типов данных и процедур.
В главе 2 языки программирования были сгруппированы в четыре поколения по признаку поддерживаемых ими абстракции: математические, алгоритмические, ориентированные на данные, объектно-ориентированные. Самые последние достижения в области развития языков программирования связаны с объектной моделью. К настоящему времени мы насчитали более сотни различных объектных и объектно-ориентированных языков. Как говорилось в главе 2, объектными принято называть языки, которые поддерживают абстракции данных и классы; объектно-ориентированными являются те объектные языки, которые поддерживают наследование и полиморфизм.
Общим предком практически всех используемых сегодня объектных и объектно-ориентированных языков является язык Simula, созданный в 1960 году Далем, Мюрхогом и Ныгардом [2]. Язык Simula основывался на идеях ALGOL, но был дополнен механизмом наследования и инкапсуляции. Но еще более существенно то, что Simula, предназначенная для описания систем и моделирования, ввела дисциплину написания программ, отражающих словарь предметной области.
Рис. А-1, заимствованный у Шмукера [3], демонстрирует генеалогию пяти наиболее влиятельных и популярных объектных или объектно-ориентированных языков программирования: Smalltalk. Object Pascal, C++, CLOS и Ada. В следующих разделах мы проанализируем некоторые из этих языков с точки зрения их "объектности".
Рис. А-1. Генеалогия объектных и объектно-ориентированных языков.
Происхождение
Развитие Smalltalk потребовало почти десятилетних усилий группы энтузиастов. Главным архитектором на протяжении почти всей работы был Дэн Ингалс (Dan Ingalls), но значительный вклад внесли также Питер Дейч (Peter Deutsh), Гленн Краснер (Glenn Krasner) и Ким МакКолл (Kim McCall). Параллельно, усилиями Джеймса Альтхофа (James Althoff), Роберта Флегала (Robert Flegal), Неда Келера (Ned Kaehler), Дианы Мерри (Diana Merry) и Стива Паца (Steve Putz) разрабатывалась оболочка Smalltalk. Адель Голдберг (Adele Goldberg) и Дэвид Робсон (David Robson) взяли на себя роль летописцев проекта.
Известны пять выпусков языка Smalltalk, обозначаемых по году их появления:
Smalltalk-72, -74. -76, -78, и самое свежее воплощение - Smalltalk-80. Реализации 1972 и 1974 годов заложили основу языка, в частности идею передачи сообщений и полиморфизм, хотя механизм наследования еще не появился. В последующих версиях полноправное гражданство получили классы; этим достигла завершения точка зрения, что все состоит из объектов. Smalltalk-80 был перенесен на многие компьютерные платформы.
Есть также один важный диалект (схожий со Smalltalk-80), получивший название Smalltalk/V. Он создан фирмой Digitalk для IBM PC (Windows и OS/2) и Macintosh. За исключением классов пользовательского интерфейса, библиотеки классов Smalltalk/V в обеих версиях практически идентичны. Среда и инструменты разработки также напоминают Smalltalk-80 [4].
Обзор
Как пишет Ингалс: "Цель проекта Smalltalk - сделать мир информации доступным для детей любого возраста. Вся трудность состоит в том, чтобы найти и применить достаточно простые и эффективные метафоры, которые позволят человеку свободно оперировать самой разнообразной информацией от чисел и текстов до звуковых и зрительных образов" [5]. В основу языка положены две простые идеи:
• все является объектами;
• объекты взаимодействуют, обмениваясь сообщениями.
В табл. А-1 приведены характеристики языка Smalltalk с точки зрения семи основных элементов объектного подхода. Множественное наследование в принципе может быть реализовано за счет переопределения некоторых методов-примитивов [6].
Абстракции Переменные экземпляра Методы экземпляра Переменные класса Методы класса Да Да Да Да
Инкапсуляция Переменных Методов Закрытые Открытые
Модульность Разновидности модулей Нет
Иерархии Наследование Шаблоны Метаклассы Одиночное Нет Да
Типизация Сильная типизация Полиморфизм Нет Да (одиночный)
Параллельность Многозадачность Непрямая (посредством классов)
Сохраняемость Долгоживущие объекты Нет
Таблица А-1. Smalltalk.
Пример
<пример пропущен>
Ссылки
Основными руководствами по языку Smalltalk являются книги "Smalltalk-80:
The Language", Голдберг и Робсон [7]; "Smalltalk-80: The Interactive Programming Environment", Голдберг [8]; "Smalltalk-80: Bit of History Words of Advice", Kpacнер, [9]. ЛаЛонд и Пух [10] подробно исследуют Smalltalk-80, в том числе библиотеки классов и средства разработки приложений.
Происхождение
Object Pascal создавался сотрудниками компании Apple Computer (некоторые из которых были участниками проекта Smalltalk) совместно с Никлаусом Виртом (Niklaus Wirth), создателем языка Pascal. Непосредственным предшественником Object Pascal является Clascal (объектно-ориентированная версия Pascal для компьютера Lisa). Object Pascal известен с 1986 года и является первым объектно-ориентированным языком программирования, который был включен в Macintosh Programmer's Workshop (MPW), среду разработки для компьютеров Macintosh фирмы Apple. Для MPW создана библиотека классов, называемая МасАрр, являющаяся основой для создания прикладных приложений, отвечающих требованиям к интерфейсу пользователя Macintosh.
Обзор
Шмукер (Schmucker) утверждает, что "Object Pascal - это "скелет" объектно-ориентированного языка [В последние годы этот язык стал очень популярен благодаря системе Delphi фирмы Borland. - Примеч. ред.]. В нем нет методов класса, переменных класса, множественного наследования и метаклассов. Эти механизмы исключены специально, чтобы сделать язык простым для изучения начинающими "объектными" программистами" [11].
В табл. А-2 приведены общие характеристики Object Pascal.
Абстракции Переменные экземпляра Методы экземпляра Переменные класса Методы класса Да Да Нет Нет
Инкапсуляция Переменных Методов Открытые Открытые
Модульность Разновидности модулей Модуль (unit)
Иерархии Наследование Шаблоны Метаклассы Одиночное Нет Нет
Типизация Сильная типизация Полиморфизм Да Да (одиночный)
Параллельность Многозадачность Нет
Сохраняемость Долгоживущие объекты Нет
Таблица А-2. Object Pascal.
Ссылки
Основным руководством по Object Pascal является "MPW Object Pascal Reference" от Apple [12].
Происхождение
Язык программирования C++ был разработан Бьерном Страуструпом, сотрудником AT&T Bell Laboratories. Непосредственным предшественником C++ является С with Classes, созданный тем же автором в 1980 году. Язык С with Classes, в свою очередь, был создан под сильным влиянием С и Simula. C++ - это в значительной степени надстройка над С. В определенном смысле можно назвать C++ улучшенным С, тем С, который обеспечивает контроль типов, перегрузку функций и ряд других удобств. Но главное в том, что C++ добавляет к С объектную ориентированность.
Известны несколько версий C++. В версии 1.0 реализованы основные механизмы объектно-ориентированного программирования, такие как одиночное наследование и полиморфизм, проверка типов и перегрузка функций. В созданной в 1989 году версии 2.0 нашли отражение многие дополнительные свойства (например, множественное наследование), возникшие на базе широкого опыта применения языка многочисленным сообществом пользователей. В версии 3.0 (1990) появились шаблоны (параметризованные классы) и обработка исключений. Комитет ANSI по C++ (X3J16) недавно одобрил предложения по введению пространств имен (что соответствует нашему обозначению категорий классов) и проверки типов во время исполнения.
Первые компиляторы C++ строились на основе препроцессора для языка С, названного cfront. Поскольку этот транслятор создавал промежуточный код на С, он позволил очень быстро перенести C++ практически на все UNIX-системы. Сейчас почти на всех платформах созданы (в том числе коммерческие) "настоящие" компиляторы C++.
Обзор
Страуструп пишет: "C++ создавался с целью избавить автора и его друзей от необходимости программировать на ассемблере, С или других современных языках такого уровня. Главной задачей было придумать язык, на котором удобно писать хорошие программы и с которым программисту приятно работать. C++ никогда не проектировался на бумаге. Его проектирование, документирование и реализация выполнялись одновременно" [13]. C++ исправил многие недостатки С и ввел описания классов, контроль типов, перегрузку функций, управление памятью, постоянные типы, ссылки, встраиваемые функции, производные классы и виртуальные функции [14].
Характеристики C++ приведены в табл. А-3.
Абстракции Переменные экземпляра Методы экземпляра Переменные класса Методы класса Да Да Да Да
Инкапсуляция Переменных Методов Открытые, защищенные, закрытые Открытые, защищенные, закрытые
Модульность Разновидности модулей файл
Иерархии Наследование Шаблоны Метаклассы Множественное Да Нет
Типизация Сильная типизация Полиморфизм Да Да (одиночный)
Параллельность Многозадачность Непрямая (посредством классов)
Сохраняемость Долгоживущие объекты Нет
Таблица А-3. C++.
Пример
Снова вернемся к задаче определения фигур. В C++ принято описывать интерфейсную часть классов в заголовочных файлах. Мы можем написать:
struct point {
int x; int y;
};
class Shape { public:
Shape(); void setCenter(Point p}; virtual void draw() = 0; Point center() const;
private
Point theCenter;
};
class Circle : public Shape { public:
Circle(); void setRadius(int r); virtual void draw(); int radius() const;
private:
int theRadius;
};
class Rectangle : public Shape { public:
Rectangle(); void setHeight(int h); void setWidth(int w); virtual void draw(); int height() conat; int width() const;
private:
int theHeigh; int theWidth;
};
class SolidRectangle : public Rectangle { public:
virtual void draw();
};
Определение C++ не предполагает наличия библиотеки классов. Для наших целей мы предположим наличие программного интерфейса Х Windows и глобальных объектов Display, window, GraphicsContext (требуемых xlib). Теперь можно завершить разработку, написав в отдельном файле реализацию методов, перечисленных выше:
Shape::Shape() {
theCenter.x = 0; theCenter.y = 0;
};
void Shape::getCenter(Point p) {
theCenter = p;
};
Point Shape::center() const {
return theCenter;
};
Circle::Circle() : theRadius(0) {};
void Circle: :setRadius( int r) {
theRadius = r;
};
void Circle::draw() {
int x = (center().x - theRadius); int y = (center().y - theRadius); XDrawArc(Display, Window, GraphicsContext, x, y, (theRadius ∙ 2), (theRadius * 2), 0, (360 ∙ 64));
};
int Circle::radius() const {
return theRadius;
};
Rectangle::Rectangle() : theHeight(0), theWidth(0) {};
void Rectangle::setHeight( int h) {
theHeight = h;
};
void Rectangle::setWidth( int w) {
theWidth = w;
};
void Rectangle::draw() {
int x = (center().x - (theWidth / 2)); int y = (center().y - (theHeight / 2)); XDrawRectangle(Display, Window, GraphicsContext, x, y, thewidth, theHeight);
};
int Rectangle::height() const {
return theHeight;
};
int Rectangle::width() const {
return thewidth;
};
void SolidRectangle::draw() {
Rectangle::draw(); int x - (center().x - (width() / 2)); int y - (center().y - (height() / 2)); gc oldGraphicsContext = GraphicsContext; XSetForeground(Display, GraphicsContext, Gray); XDrawFilled(Display, Window, GraphicsContext, x, y, width(), height()); GraphicsContext = OldGraphicsContext;
};
Ссылки
Основной ссылкой по C++ является "Annotated C++ Reference Manual" Эллис и Страуструпа [15]. Кроме того, Страуструп [16] предложил углубленный анализ языка и его использования в контексте объектно-ориентированного проектирования.
Происхождение
Существуют буквально десятки диалектов языка Lisp, включая MacLisp, Standard Lisp, SpiceLisp, S-1 Lisp, ZetaLisp, Nil, InterLisp и Scheme. В начале 80-х годов под воздействием идей объектно-ориентированного программирования возникла серия новых диалектов Lisp, многие из которых были ориентированы на представление знаний. Успех в стандартизации Common Lisp стимулировал попытки стандартизировать объектно-ориентированные диалекты в 1986 году.
Идея стандартизации была поддержана летней конференцией ACM по Lisp и функциональному программированию 1986 года, в результате чего была создана специальная рабочая группа при комитете X3J13 ANSI (комитет по стандартизации Common Lisp). Поскольку новый диалект должен был стать надстройкой над Common Lisp, он получил название Common Lisp Object System (Объектная система Common Lisp) или, сокращенно, - CLOS. Возглавил комитет Дэниел Бобров (Daniel Bobrow), а его членами стали Соня Кин (Sonya Keene), Линда де Мичил (Linda DeMichiel), Патрик Дассад (Patrick Dussud), Ричард Габриель (Richard Gabriel), Джеймс Кемпф (James Kempf), Грегор Кисазлес (Gregor Kicazles) и Дэвид Мун (David Moon).
Серьезное влияние на проект CLOS оказали языки NewFlavors и CommonLoops. После двухлетней работы, в 1988 году была опубликована полная спецификация CLOS.
Обзор
Кип отмечает, что в проекте CLOS ставились три основные цели. CLOS должен:
• представлять собой стандартное расширение языка, включающее все наиболее полезные свойства существующей объектно-ориентированной парадигмы;
• обеспечить эффективный и гибкий интерфейс программиста, позволяющий реализовать большинство прикладных задач;
• проектироваться как расширяемый протокол, так, чтобы можно было изменять его поведение, тем самым стимулируя дальнейшие исследования в области объектно-ориентированного программирования [17].
Обзор характеристик CLOS можно найти и табл. А-4. Не поддерживая непосредственно механизм долгоживущих объектов, CLOS имеет расширения с протоколом метаобъектов, реализующих этот механизм [18].
Абстракции Переменные экземпляра Методы экземпляра Переменные класса Методы класса Да Да Да Да
Инкапсуляция Переменных Методов Чтение, запись, доступ Открытые
Модульность Разновидности модулей Пакет
Иерархии Наследование Шаблоны Метаклассы Множественное Нет Да
Типизация Сильная типизация Полиморфизм Возможна Да (множественный)
Параллельность Многозадачность Да
Сохраняемость Долгоживущие объекты Нет
Таблица А-4. CLOS.
Ссылки
Основным руководством по языку CLOS является -"Common Lisp Object System Specification" [19].
Происхождение
Министерство обороны США, возможно, самый крупный в мире пользователь компьютеров. В середине 70-х годов программные разработки этого департамента достигли критической точки: проекты выходили из временных и бюджетных рамок, а заданных характеристик достичь не удавалось. Стало очевидно, что дальше ситуация только ухудшится, стоимость разработки программных систем взлетит еще выше, а потребность в программах будет расти экспоненциально. Для решения всех этих проблем, отягощенных вдобавок наличием сотен языков программирования, министерство обороны профинансировало проект создания единого общего языка высокого уровня. В некотором смысле Ada является одним из первых языков программирования, выпущенных промышленным способом. Исходные требования были сформулированы в 1975 году (Steelman) и реализованы в 1978 году. Был объявлен международный конкурс, на который откликнулось 17 участников. Это число затем было сокращено до четырех, затем до двух, и наконец до одного; при этом в проектировании и испытаниях участвовали сотни ученых по всему миру.
Проект-победитель вначале носил условное наименование Green (в конкурсе проект имел зеленый кодовый знак); позднее он получил имя Ada в честь Ады Августы графини Лавлейс (Ada Augusta Lovelace), которая была удостоена этой чести за свои соображения о потенциальных возможностях компьютеров. Основным разработчиком языка был Жан Икбьян (Jean Ichbian) из Франции. В команду разработчиков входили: Бернд Криг-Брюкнер (Bernd Krieg-Brueckner), Бриан Вичман (Brian Wichmann), Анри Ледгар (Henry Ledgard), Жан-Клод Ельяр (Jean-Claude Heliard), Жан-Лу Гайли (Jean-Loup Gailly), Жан-Раймон Абриаль (Jean-Raymond Abrial), Джон Барнс (John Barnes), Майк Вуджер (Mike Woodger), Оливье Рубин (Olivier Roubine), С. А. Шуман (S. A. Schumann) и С. С. Весталь (S. С. Vestal).
Непосредственными предшественниками Ada являются Pascal и его производные, включая Euclid, Lis, Mesa, Modula и Sue. Были использованы некоторые концепции ALGOL-68, Simula, CLU и Alphard. Стандарт ANSI для Ada был окончательно издан в 1983 году. Трансляторы Ada, хотя и не сразу, были реализованы для всех основных архитектур. Будучи созданным благодаря министерству обороны, язык Ada сегодня используется во многих государственных и коммерческих проектах. Ada - традиционный язык разработки больших и сложных систем, например, системы управления воздушным движением в США и Канаде. Стандарты ANSI должны пересматриваться каждые пять лет, поэтому в настоящее время изучается проект Ada 9x. В нем в исходное определение языка внесен ряд незначительных исправлений: уточнения, устранение очевидных пробелов, исправления ошибок. В настоящем виде Ada является объектным, но не объектно-ориентированным языком. Проект 9x подразумевает расширение языка до уровня объектно-ориентированного.
Обзор
Разработчики Ada прежде всего беспокоились о:
• надежности и эксплуатационных качествах программ;
• программировании как разновидности человеческой деятельности;
• эффективности [20].
В табл. А-5 приведены основные характеристики языка Ada с точки зрения объектного подхода.
Абстракции Переменные экземпляра Методы экземпляра Переменные класса Методы класса Да Да Нет Нет
Инкапсуляция Переменных Методов Открытые, закрытые Открытые, закрытые
Модульность Разновидности модулей Пакет
Иерархии Наследование Шаблоны Метаклассы Нет (входит в Ada9x) Да Нет
Типизация Сильная типизация Полиморфизм Да Нет (входит в Ada9x)
Параллельность Многозадачность Да
Сохраняемость Долгоживущие объекты Нет
Таблица А-5. Ada. Ссылки
Основным руководством по языку Ada является "Reference Manual for the Ada Programming Language" [21].
Происхождение
Автор Eiffel Бертран Мейер (Bertrand Meyer) создавал не только язык объектно-ориентированного программирование, но и инструмент проектирования программ.
Несмотря на сильное влияние Simula, Eiffel - вполне самостоятельный объектно-ориентированный язык со своей собственной средой разработки.
Eiffel поддерживает динамическое связывание и статическую типизацию, тем самым обеспечивая гибкость интерфейсов классов в сочетании с безопасным использованием типов. В Eiffel есть несколько важных черт, поддерживающих более жесткий стиль программирования, в том числе параметризованные классы, утверждения и исключения. Мейер считает, что обобщенные классы хорошо дополняют наследование, учитывая горизонтальный уровень общности; новые классы на одном уровне иерархии можно создавать, используя тип в качестве параметра, а не плодя практически одинаковые подклассы.
Неотъемлемой частью языка являются пред- и постусловия, то есть утверждения, которые должны выполняться при входе в метод и выходе из него. Нарушение утверждения вызывает исключительную ситуацию. Ее можно перехватить, обработать и попробовать вызвать тот же метод еще раз.
Обзор
Eiffel поощряет хорошее программирование, добротную спецификацию классов, сильную типизацию и повторное использование, как через наследование, так и через параметризацию. Формальная трактовка исключительных ситуаций позволяет жестко специфицировать интерфейсы классов при реализации.
Eiffel предоставляет законченную среду разработки программ, включая специальный редактор с выделением синтаксиса, генератор документации, библиотеки классов и броузер. Кроме того, поддерживаются средства управления кодом и сборкой программ.
Свойства языка с точки зрения нашей модели показаны в табл. А-6.
Абстракции Переменные экземпляра Методы экземпляра Переменные класса Методы класса Да Да Нет Нет
Инкапсуляция Переменных Методов Закрытые Открытые, закрытые
Модульность Разновидности модулей Блок (unit)
Иерархии Наследование Шаблоны Метаклассы Множественное Да Нет
Типизация Сильная типизация Полиморфизм Да Да
Параллельность Многозадачность Нет
Сохраняемость Долгоживущие объекты Нет
Таблица А-6. Eiffel.
Ссылки
Лучше всего взять книгу Мейера "Object Oriented Software Construction" [22].
На рис. А-2 вы найдете названия многих важных объектных и объектно-ориентированных языков, в библиографии есть ссылки на информацию о большинстве из них.
<рисунок пропущен>