Дональд Бокс - Сущность технологии СОМ. Библиотека программиста
- Название:Сущность технологии СОМ. Библиотека программиста
- Автор:
- Жанр:
- Издательство:Питер
- Год:2001
- Город:СПб
- ISBN:5-318-00058-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Дональд Бокс - Сущность технологии СОМ. Библиотека программиста краткое содержание
В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.
Сущность технологии СОМ. Библиотека программиста - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Когда клиенты, заказавшие изменения, получают модернизированный FastString , они включают новое определение класса и DLL в систему контроля своего исходного кода и запускают тестирование нового и улучшенного FastString . Подобно разработчику библиотеки, они тоже приятно удивлены: для того, чтобы воспользоваться преимуществами новой версии Length , не требуется никаких модификаций исходного кода. Вдохновленная этим опытом, команда разработчиков убеждает начальство включить новую DLL в окончательный «золотой» CD, уже готовый для выпуска. Это тот редкий случай, когда руководство идет навстречу энтузиастам-разработчикам и включает в окончательный продукт новую DLL. Подобно большинству программ инсталляции, описание установки клиентской программы настроено на молчаливое (без предупреждения) замещение всех старых версий FastString DLL, какие есть на машине конечного пользователя. Это выглядит вполне безобидно, поскольку эти изменения не затронули открытый интерфейс класса, так что тотальная молчаливая модернизация под версию 2.0 FastString только улучшит любые имеющиеся клиентские приложения, которые были установлены раньше.
Представим себе следующий сценарий: конечные пользователи наконец-то получают свои экземпляры вожделенного продукта. Каждый из них тут же бросает все и устанавливает новое приложение на свою машину, дабы попробовать его. После того как высохли слезы восторга от того, что наконец-то можно делать быстрый текстовый поиск, пользователь возвращается к его или ее нормальному состоянию и запускает ранее установленное приложение, которое также имеет неосторожность использовать DLL FastString . Первые несколько минут всё идет хорошо. Затем внезапно появляется сообщение, что возникла исключительная ситуация и что вся работа конечного пользователя пропала. Он пытается запустить приложение снова, но на этот раз диалоговое окно об исключительной ситуации появляется почти сразу. Конечный пользователь, привычный к употреблению современного программного обеспечения, переустанавливает операционную систему и все приложения, но даже это не спасает от повторения исключительной ситуации. Что же произошло?

А произошло то, что разработчик библиотеки был убаюкан верой в то, что C++ поддерживает инкапсуляцию. Хотя C++ и поддерживает синтаксическую инкапсуляцию через свои закрытые и защищенные ключевые слова, в стандарте C++ ничего не сказано о двоичной инкапсуляции. Это происходит потому, что модель трансляции C++ требует, чтобы клиентский компилятор имел доступ ко всей информации относительно двоичного представления объектов, – с целью обработать экземпляр класса или делать невиртуальные вызовы метода. Это включает в себя информацию о размере и порядке закрытых и защищенных элементов данных объекта. Рассмотрим сценарий, показанный на рис. 1.3. Версия 1.0 FastString требует четыре байта на экземпляр (принимая sizeof(char *) == 4 ). Клиенты написанного под версию 1.0 определения класса выделяют четыре байта памяти под вызов конструктора класса. Конструктор, деструктор и методы версии 2.0 (а именно эти версии содержатся в DLL в машине конечного пользователя) ожидают, что клиент выделил восемь байт на экземпляр (принято sizeof(int) == 8 ), и не предусматривают собственных резервов для записи во все восемь байт. К сожалению, у клиентов с версией 1.0 вторые четыре байта этого объекта на самом деле принадлежат кому-то другому, и запись в это место указателя на текстовую строку недопустима, о чем и сообщает диалог исключительной ситуации.
Существует общее решение проблемы версий – переименовывать DLL всякий раз, когда появляется новая версия. Такая стратегия принята в Microsoft Foundation Classes (MFC). Когда номер версии включен в имя файла DLL (например, FastString10.DLL , FastString20.DLL ), клиенты всегда загружают ту версию DLL, с которой они были сконфигурированы, независимо от присутствия в системе других версий. К сожалению, со временем, из-за недостаточного опыта в системном конфигурировании, число версий DLL, имеющихся в системе конечного пользователя, может превысить реальное число пользовательских приложений. Чтобы убедиться в этом, достаточно проверить системный каталог любого компьютера, проработавшего больше шести месяцев.
В конечном счете, проблема управления версиями коренится в модели трансляции C++, не рассчитанной на поддержку независимых двоичных компонентов. Требуя знания клиентом двоичного представления объектов, C++ предполагает тесную двоичную связь между клиентом и исполняемыми программами объекта. Обычно такая связь является преимуществом C++, так как она позволяет трансляторам генерировать весьма эффективный код. К сожалению, эта тесная двоичная связь не позволяет переместить реализации класса без проведения клиентом повторной компиляции. По причине этой связи и несовместимости транслятора и компоновщика, упомянутых в предыдущем разделе, простой экспорт определений класса C++ из DLL не обеспечивает приемлемой архитектуры двоичных компонентов.
Отделение интерфейса от реализации
Концепция инкапсуляции основана на разделении того, как объект выглядит (его интерфейса), и того, как он в действительности работает (его реализации). Проблема в C++ в том, что этот принцип неприменим на двоичном уровне, так как класс C++ одновременно является и интерфейсом, и реализацией. Этот недостаток может быть преодолен, если смоделировать две новые абстракции, являющиеся классами C++, но различающиеся по своей сущности. Если определить один класс C++ как интерфейс для типа данных, а второй – как саму реализацию типа данных, то конструктор объектов теоретически может модифицировать некоторые детали класса реализации, в то время как класс интерфейса останется неизменным. Все, что нужно, – это выдержать соотношение интерфейса с его реализацией так, чтобы не показывать клиенту никаких деталей реализации.
Класс интерфейса должен содержать только такое описание основных типов данных, какое должен, по мнению разработчика, представлять себе клиент. Поскольку интерфейс не должен сообщать ни о каких деталях реализации, класс интерфейса C++ не может содержать никаких элементов данных, которые могут быть использованы в реализации объекта. Вместо этого класс интерфейса должен содержать только описания методов для каждой открытой операции объекта. Класс реализации C++ будет содержать фактические элементы данных, необходимые для обеспечения функционирования объекта. Одним из простейших подходов является использование класса-дескриптора (handle-class) в качестве интерфейса. Класс-дескриптор мог бы просто содержать непрозрачный (opaque) указатель, чей тип никогда не может быть полностью определен клиентом. Следующее определение класса демонстрирует эту технику:
Читать дальшеИнтервал:
Закладка: