Здравствуйте!
В поисковиках русскоязычное что-то искал - не нашёл. Подскажите пожалуйста где почитать, чтобы понятно для не гуру было как реализуется подобная архитектура в CL?
Есть желание реализовать приложение с поддержкой плагинов. Не факт, что будут поддерживаться плагины сторонних авторов. В данном случае это архитектурное решение. (Начитался "Чистая архитектура" Роберт Мартин и решил понять как бы я эти принципы реализовал бы в CL для своего хобби-проекта :-) ).
Абстрактный пример отражающий суть вопроса:
Есть некий программный комплекс. Состоит из пакетов/модулей A, B и C:
- модуль A реализует бизнес-логику;
- модуль B реализует UI;
- модуль C реализует работу с абстрактным "хранилищем" (БД как частный случай).
Логично, что "поток управления" будет исходить из A чаще всего. Т.е. запускается A, передаёт управление B чтобы получить какую-то информацию от пользователя (уже структурированную B в удобоваримую форму для A), что-то нужное для бизнес-логики читает/пишет в C, думает :-) и выдаёт результат в B.
Передача управления упрощённо: A -> B -> A -> C -> A -> B.
При этом с точки зрения архитектуры классно было бы сделать так, чтобы B зависел от A, C зависел от A, A ничего не знал о существовании B и C. B и C могут быть в проекте как плагины, могут быть заменены в любой момент (пусть даже с перезапуском приложения, требования менять модули "на лету" нет). Например могут быть несколько модулей B, реализующих Web UI, command line, native UI и т.п. И несколько C - SQL, текстовый файл, ещё что-то неведомое. И конкретный выбор какую реализацию таких "плагинов" использовать может быть как в исходнике описываться, так и в конфиге приложения.
Дерево зависимостей упрощённо: B -> A <- C.
В ЯП со статической типизацией решалось бы просто - интерфейс взаимодействия между A и B реализуем в форме интерфейса класса B внутри модуля A. Модуль B включает в свои зависимости модуль A и предоставляет реализацию этого интерфейса. Аналогично для A и C.
Другими словами - Как сделать так, чтобы исходный код A не подозревал о существовании B и C, но тем не менее использовал их функционал?
Что используется в CL для реализации такого подхода? Киньте ссылок почитать пожалуйста. Желательно на русском, либо в формате удобоваримом для online-переводчика.
Благодарю за ваше внимание. Я новичок в программировании. Хочется научиться делать такие вещи правильно, чтобы гибко к изменениям было и понятно через несколько лет что делает тот или иной код/модуль/пакет.
P.S. В тексте я использовал термины "модуль" и "пакет". В данном случае я имею ввиду пакеты CL, просто мне проще думать в терминах "модуль" как о некой "вещи в себе" с интерфейсом торчащим наружу.