vak: (Default)
[personal profile] vak
Пусть что у нас есть два программных модуля, которые взаимодействуют между собой. Один модуль вызывает другой, и наоборот. Для масштаба представьте, что один модуль это Microsoft Word, а другой - Microsoft Windows. Вы нажали клавишу - драйвер клавиатуры формирует событие, Windows передаёт его в Word, тот вставляет букву в файл и шлёт запрос к Windows, чтобы нарисовать её на экране.

Софт такого уровня обычно разрабатывают на языках со статической типизацией, скажем С++. Что означает взаимодействие модулей для программиста? Это означает, что в исходный код вызывающего модуля мы включаем include-файл от вызываемого модуля. В нём определены функции и структуры данных, нужные нам для обращения к этому модулю. Если бы все программы строились по этому принципу, это был бы кошмар. Любое изменение в структурах данных Windows, даже простейшее, приводило бы к необходимости пересобрать не только Windows, но и Word, и тысячи других программ. Мало того, изменения в Word или браузере, или игрушках вызывали бы перекомпиляцию самого Windows. К счастью, этого не происходит, потому как архитекторы давно додумались до принципа инверсии зависимостей (Dependency inversion principle).

Типичный случай двух взаимодействующих модулей. Каждый модуль вызывает другой, а значит, зависит от его исходников.



Правильное решение проблемы - выделение межмодульных интерфейсов в отдельные компоненты (абстрактные классы в Си++). Интерфейсы не содержат деталей реализации, и поэтому слабо подвержены изменениям. Вот такая ситуёвина получается:



Пример из жизни: интерфейс системных вызовов ядра Линукса крайне редко меняется. Поэтому при обновлении ядра все приложения продолжают работать.

Я сбацал пример, фактически шаблон для разделения интерфейсов взаимодействующих классов в Си++. Посмотреть можно на Гитхабе: https://github.com/sergev/dependency-inversion-demo

Date: 2021-01-06 16:07 (UTC)
ircicq: (Default)
From: [personal profile] ircicq
Так и пишут компоненты по технологии COM.
Ну или CORBA, для тех кто не любит MS

Date: 2021-01-06 17:12 (UTC)
From: [personal profile] dijifi
Была такая штука под названием Taligent. Писалась на честном C++, с классами и интерфейсами. Время сборки ядра - неделя, за счёт бедного линкера.

DLLs и подобные технологии решают эту проблему (за счёт того, что линк делается только на то что действительно нужно). Но в этот момент от C++ и headers там остались только рожки да ножки. Отлаживать приходится в бинарниках.

Если нужно решать эти проблемы на уровне c++, компилировать придётся при install (или чаще).