Основы объектно-ориентированного программирования - Бертран Мейер
Шрифт:
Интервал:
Закладка:
-- Добавить c в конец файла.
require
write_open: open_for_write
external
"C" alias "_char_write";
ensure
one_more: count = old count + 1
end
Предложение alias факультативно и используется, только если оригинальное имя внешней программы отличается от имени, данного в классе. Это случается, когда внешнее имя недопустимо в ОО-нотации, например, имя, начинающееся с символа подчеркивания (используемое в языке С).
Улучшенные варианты
Описанный механизм включает большинство случаев и достаточен для целей описания нашей книги. На практике полезны некоторые уточнения:
[x]. Некоторые внешние программные элементы могут быть макросами. Они имеют вид подпрограмм в ОО-мире, но любой их вызов предполагает вставку тела макроса в точке вызова. Этого можно достичь вариацией имени языка (как, например, "C:[macro]...").
[x]. Необходимо также разрешить вызовы программ из "динамически присоединяемых библиотек" (DLL), доступных в Windows и других платформах. Программа DLL загружается динамически во время первого вызова. Имя программы и библиотеки разрешается также задавать динамически в период выполнения. Поддержка DLL должна включать как способ статической спецификации имени, так и полностью динамический подход с использованием библиотечных классов DYNAMIC_LIBRARY и DYNAMIC_ROUTINE. Эти классы можно инициализировать во время выполнения, создавая объекты, представляющие динамически определенные библиотеки и подпрограммы.
[x]. Необходима и связь в обратном направлении, позволяющая не объектному ПО создавать объекты и вызывать компоненты. Например, графической системе может понадобиться механизм обратного вызова (callback mechanism), вызывающий определенные компоненты класса.
Все эти возможности присутствуют в ОО-среде, описанной в последней лекции. Однако их подробное обсуждение - это отдельный разговор.
Использование внешних программ
Внешние программы являются частью ОО-метода, помогая сочетать старое ПО с новым. Любой метод проектирования ПО, допускающий возможность повторного использования, должен допускать программный код, написанный на других языках. Трудно было бы убедить потенциального пользователя, что надо отказаться от всего существующего ПО, поскольку с этой минуты начинается повторное использование.
Открытость остальному миру - требование большинства программных продуктов. Это можно назвать принципом скромности: авторы новых инструментов должны дать возможность пользователям иметь доступ к ранее имевшимся возможностям.
Внешние программы также необходимы для обеспечения доступа к аппаратуре и возможностям операционной системы. Типичный пример - класс файлов. Другой пример - класс ARRAY, чей интерфейс рассматривался в предыдущих лекциях, и чья реализация основана на внешних программах: процедура создания make использует программу распределения памяти, функция доступа item использует внешний механизм для быстрого доступа к элементам массива, и т.д.
Эта техника обеспечивает ясный интерфейс между ОО-миром и другими подходами. Для клиентов внешняя программа - это просто программа. В примере, программа на С _char_write обрела статус компонента (feature) класса, дополнена предусловием и постусловием и получила стандартное имя put. Возможности, внутренне опирающиеся на не ОО-механизмы, получают новую упаковку абстрактных данных, так что участники ОО-мира начинают рассматривать их как законных граждан сообщества, и их низкое происхождение никогда не упоминается в "изысканном обществе". ("Изысканное общество" не означает бесклассовое.)
ОО-изменение архитектуры (re-architecturing)
Понятие внешней программы хорошо соответствует остальной части подхода. Основной вклад метода - архитектурный: объектная технология говорит, как разработать структуру систем, чтобы обеспечить расширяемость, надежность и повторное использование. Она также говорит, как заполнить эту структуру. Но что по-настоящему определяет, является ли система объектной, - так это ее модульная организация. Для использования ОО-архитектуры часто разумно использовать прием, называемый обертыванием (wrap), одевая в одежды класса внутренние элементы.
Крайний, но не совсем абсурдный, способ использования нотации - построить систему полностью на внешних программах. Объектная технология тогда служит просто инструментом упаковки, использующим мощные механизмы инкапсуляции: классы, утверждения, скрытие информации, клиент, наследственность.
Но обычно нет причины заходить так далеко. ОО-нотация адекватна вычислениям любого рода и столь же эффективна, как и вычисления на языках Fortran или C. В каких случаях полезна ОО-инкапсуляция внешнего ПО? Один из них мы видели: обеспечение доступа к операциям, зависящим от платформы. Другой - проблема многих организаций - управление старым ПО, доставшимся в наследство и продолжающим широко использоваться. Объектная технология предлагает возможность обновления таких систем, изменяя их архитектуру, но не переписывая их полностью.
Эта техника, которую можно назвать ОО-перестройкой (object-oriented re-architecturing) дает интересное решение сохранения ценных свойств существующего ПО, готовя его к будущему расширению и эволюции.
Однако для этого необходимы определенные условия:
[x]. Необходимо суметь подобрать хорошие абстракции для старого ПО, которое, не будучи объектным, как правило, имеет дело с абстракциями функций, а не данных. Но в этом и состоит задача - обернуть старые функции в новые классы. Если с выделением абстракций не удастся справиться, то никакая ОО-перестройка не поможет.
[x]. Наследуемое ПО должно быть хорошего качества. Перестроенное старье остается старьем - возможно хуже первоначального, поскольку оно будет скрыто под слоями абстракции.
Эти два требования частично сходны, поскольку качество любого ПО в значительной степени определяется качеством его структуры.
Когда они выполнены, можно использовать внешний механизм для построения интересного ОО-программного продукта, основанного на прежних разработках. Приведем два примера, являющихся частью среды, описанной в последней лекции.
[x]. Библиотека Vision (библиотеки описываются в лекции 14 курса "Основы объектно-ориентированного проектирования") дает переносимую графику и механизмы пользовательского интерфейса, позволяющие разработчикам создавать графические приложения для многих различных платформ с ощущением обычной перекомпиляции. Внутренне, она основана на "родных" механизмах, используемых во внешних программах. Точнее, ее нижний уровень инкапсулирует механизмы соответствующих платформ.
[x]. Другая библиотека, Math, обеспечивает широкий набор возможностей численных вычислений в таких областях как теория вероятностей, статистика, численное интегрирование, линейные и нелинейные уравнения, дифференциальные уравнения, оптимизация, быстрое преобразование Фурье, анализ временных рядов. Внутренне она основана на коммерческой библиотеке подпрограмм, библиотеке NAG от Nag Ltd., Oxford, но обеспечивает пользователям ОО-интерфейс. Библиотека скрывает используемые ею программы и предлагает абстрактные объекты, понятные математику, физику или экономисту, представленные классами: INTEGRATOR, BASIC_MATRIX, DISCRETE_FUNCTION, EXPONENTIAL_DISTRIBUTION. Прекрасные результаты достигаются благодаря качеству внешних программ - NAG аккумулирует сотни человеко-лет разработки и реализации численных алгоритмов. К нему добавлены ОО-преимущества: классы, скрытие информации, множественное наследование, утверждения, систематическая обработка ошибок через исключительные ситуации, согласованное именование.
Эти примеры типичны для сочетания лучших традиционных программных продуктов и объектной технологии.
Вопрос совместимости: гибридный программный продукт или гибридные языки?
Теоретически, мало кто не согласится с принципом скромности или будет отрицать необходимость механизма интеграции между ОО-разработками и старым ПО. Противоречия возникают, когда выбирается уровень интеграции.
Многие языки - самыми известными являются Objective-C, C++, Java, Object Pascal и Ada 95 - пошли по пути добавления ОО-конструкций в существовавший не ОО-язык. Они известны как гибридные языки (hybrid languages) - см. лекцию 17 курса "Основы объектно-ориентированного проектирования".
Техника интеграции, описанная выше, основывалась на внешних программах и ОО-перестройке. Это другой принцип: необходимость в совместимости ПО не означает перегрузку языка механизмами, могущими расходиться с принципами объектной технологии.