Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Роджерсон Д. - Основы COM - 2000.pdf
Скачиваний:
412
Добавлен:
13.08.2013
Размер:
2.4 Mб
Скачать

133

Внешний компонент

Инструмент

преобразования

IToolInfo

ISetColors

Внутренний компонент

Алгоритм

преобразования

IMorph

IColors

Рис. 8-7 Интерфейс IToolInfo — это метаинтерфейс, вероятность конфликта которого с интерфейсами внутреннего компонента мала. ISetColors не является метаинтерфейсом и действует в области компетенции внутреннего компонента.

ISetColors конфликтует с интерфейсом IColors внутреннего компонента.

Взаимосвязанные пары

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

Агрегирование и включение в реальном мире

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

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

Для устранения этих недостатков компонент можно спроектировать так, чтобы способствовать повторной применимости. То же самое верно и для классов С++, которые трудно, если не невозможно, расширять или специализировать, если они не спроектированы надлежащим образом. Классы С++, разработанные с учетом последующей настройки, имеют «защищенные» методы, которые используются производным классом для получения информации о внутреннем состоянии базового класса. Компоненты СОМ могут использовать интерфейсы для того, чтобы облегчить свое включение или агрегирование.

Предоставление информации о внутреннем состоянии

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

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

134

Внешний компонент

 

IX

 

 

Внешний компонент использует

Реализация

IInternalState для получения

внешнего компонента

дополнительной информации о

 

состоянии внутреннего

Внутренний компонент

 

IInternalState

 

IY

IInternalState предоставляет

 

внешнему компоненту

IZ

информацию о внутреннем

состоянии данного компонента

Рис. 8-8 Внутренний компонент может упростить свою настройку, предоставив интерфейсы, которые дают внешнему компоненту доступ к его внутреннему состоянию

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

Независимо реализованные интерфейсы

 

 

 

 

 

 

 

 

IX

 

Реализация IX

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

IY

 

Реализация IY

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

IZ

 

Реализация IZ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Реализации интерфейсов редко бывают независимыми

Интерфейсы с общей реализацией

IX

 

IY

Реализация

IX, IY, IZ

 

IZ

 

Обычно реализации интерфейсов

 

взаимосвязаны

Рис. 8-9 Клиент рассматривает интерфейсы как независимые сущности. Однако обычно интерфейсы используют общие детали реализации. Это еще более затрудняет расширение или специализацию компонентов. Добавление интерфейсов, предоставляющих взгляд на компонент изнутри, может упростить его настройку.

Моделирование виртуальных функций

Дополнительные интерфейсы могут не только предоставить эквивалент СОМ для защищенных функций-членов С++, но и позволить интерфейсам замещать виртуальные функции. Во многих случаях виртуальные функции используются как функции обратного вызова (callback). Базовый класс может вызывать виртуальную функцию до, во время или после некоторой операции, чтобы дать производному классу возможность модифицировать ее выполнение. Компоненты СОМ могут делать то же самое, определив интерфейс настройки (customization interface). Компонент не реализует такой интерфейс, а, наоборот, вызывает его. Клиенты, желающие настроить компонент для своих нужд, реализуют интерфейс настройки и передают указатель на него компоненту. Эту технику клиенты могут применять, и не используя включение или агрегирование (рис. 8-10).

Клиент

Клиент использует IX

ICustomize

Компонент

IX

Компонент вызывает

ICustomize, чтобы дать клиенту возможность настройки поведенияIX

Рис. 8-10 Компонент определяет исходящий интерфейс, который он вызывает для своей настройки

Соседние файлы в предмете Программирование на C++