Визуальное программирование и MFC

       

Эмуляция


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

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

Это нечто называется эмуляцией. Идея проста: пусть клиент вызывает CoCreateInstance со старым CLSID, но на самом деле будет создаваться экземпляр нового объекта. Для поддержки этого СОМ предоставляет функцию CoTreatAsClass с двумя параметрами: старым и новым CLSID. После вызова соответствующей функции результатом попыток создания объектов с использованием старого CLSID будет создание объектов с новым CLSID. (Реализация этого вызова обычно осуществляется путем записи отношения эмуляции между двумя CLSID в системный реестр.) Объекты нового класса поддерживают и все интерфейсы старого, поэтому существующие клиенты продолжают работать как прежде.

Данный механизм может применяться и для создания абстрактных компонентов вроде объекта — корректора орфографии, описанного выше. Например, текстовые процессоры могли бы использовать только один CLSID для идентификации объекта — корректора орфографии, поддерживающего стандартизированный интерфейс ISpellChecker. Но так как CLSID в СОМ задает некоторую реализацию интерфейса, то объекты — корректоры орфографии разных производителей будут иметь разные CLSID, хотя оба поддерживают один и тот же интерфейс. В таком случае можно определить стандартный CLSID, который будет просто обозначать "корректор орфографии". Текстовый процессор будет всегда использовать для создания объекта — корректора орфографии именно этот CLSID. Чтобы на данной системе запускался конкретный корректор, с помощью функции CoTreatAsClass задается отображение CLSID абстрактного корректора орфографии в CLSID выбранного объекта-корректора.



Содержание раздела