Программирование монолитных приложений .exe имеет ряд недостатков:
- Модификация приложений ведет к перекомпиляции
- Ограниченная масштабируемость.
- Сложность адаптации.
В таком случае противопоставлением монолитному приложению является компонентное (состоящее из нескольких законченных частей). Достоинства компонентов:
- Удобство и гибкость модернизации приложений.
- Адаптация приложения.
- Сборка приложений на основе компонентов из библиотеки.
- Распределённые вычисления.
Компонент – скомпилированный (бинарный) модуль, представляющий свои услуги через строго определённые стыковочные узлы – интерфейсы.
Компонентно-ориентированное приложение.
Требования к компонентам:
- Динамическая компоновка.
- Инкапсуляция:
- Сокрытие языка программирования.
- Распространение в двоичном формате.
- Неизменность интерфейсов.
- Прозрачность перемещения компонентов по сети
Для программирования компонентов применяется технология COM.
COM - это спецификация метода создания компонентов и построения из них приложений. Т.е. она определяет стандарт, которому должны следовать компоненты, чтобы гарантировать возможность совместной работы.
Виды компонентов COM:
- Компоненты внутри процесса (In Process Server), эти компоненты реализуются в виде библиотек DLL (Dynamic Link Library) и загружаются в адресное пространство приложения-клиента.
- Компоненты вне процесса (Local / Remote Server). Реализуются в виде исполняемых файлов (exe), существуют в другом процессеи могут выполняться на разных с клиентом компьютерах
Интерфейс компонента – это
- спецификация компонента
- публичные члены-данные и члены-функции класса
- чисто-абстрактный класс, определяющий только методы и свойства, ожидаемые у компонента
Интерфейс COM – специальная структура в памяти (VTBL – Virtual Function Table)
Чтобы компонент следовал спецификации COM, его интерфейсы должны наследовать специальный интерфейс, определённый в COM – IUnknown.
- QueryInterface(). Запрашивает у компонента другой интерфейс по его идентификатору (IID).
- AddRef(). Увеличивает число ссылок на интерфейс.
- Release(). Уменьшает число ссылок на интерфейс.
Клиент компонента не может определять сам, когда удалить компонент из памяти, вместо этого он должен сообщать компоненту, что ему нужен интерфейс или он закончил с ним работать.
Относительно Unknown существуют следующие соглашения:
- Вы всегда получаете один и тот же IUnknown.
- Вы можете снова получить интерфейс, если получали его раньше.
- Вы можете получить интерфейс, который у вас уже есть.