Вкратце о задаче — есть приложение, состоящие из кучи разных сущностей (я их называю модулями). К примеру модуль драйвера каких-то железок, журнала, таймеров, отправки смс, прикладной функциональности, общения с другим ПО, лога и т.п.
Нужные модули создаются в зависимости от конфига при старте и уничтожаются при завершении работы.
Модуль при создании создает и настраивает объекты, которые собственно будут решать задачу. Иногда для этого нужны объекты из других модулей — к примеру драйверу нужен таймер и журнал и т.п.
Как я понимаю, это что-то вроде сервис-локатора — центральное хранилище, у которого можно затребовать модуль по имени / типу, а он будет создан или выдан имеющийся.
Иногда получается многофазная инициализация — к примеру драйвер использует журнал, но ему надо зарегистрировать в журнале свои события, чтобы журнал мог подгрузить настройки регистрации этих событий.
Сейчас у меня сделано так — у модуля есть метод void load(int step), и есть шаги загрузки от 1 до 10. Система дергает все методы на шаге 1, затем на шаге 2 и т.д. А в доке написано, что скажем вызвать Journal::regEvent можно на шагах 1-5. Соответственно на шаге 6 журнал выполняет загрузку данных и попытка вызвать Journal::regEvent закончится ошибкой.
Проблема в том, что надо это все помнить и аккуратно вручную разруливать. Опять же, если придется поменять допустимые шаги для вызова метода — надо перелопатить код, который его вызывает.
Здравствуйте, enji, Вы писали:
E>Сейчас у меня сделано так — у модуля есть метод void load(int step), и есть шаги загрузки от 1 до 10. [...] E>Как можно сделать удобнее?
А получится заменить void load(int step) на template<int step> void load() или нечто подобное (типа template<int step> void load(Token<step> token))?
Если да, то можно добавить требование соответствующего токена в Journal::regEvent.
Если же step это всегда runtime значение, то можно заставить пользователя его проверять. Тут недавно всплывала подобная тема: 1
Здравствуйте, enji, Вы писали: E>Модуль при создании создает и настраивает объекты, которые собственно будут решать задачу. Иногда для этого нужны объекты из других модулей — к примеру драйверу нужен таймер и журнал и т.п.
делаете центральную точку доступа — синглон. я ее обычно называю Core
она и задает порядок инициализации
если хочется сделать порядок инициализации ну прямо сильно гибким, то делайте ленивую инициализацию — при первом обращении к Core::get_driver() или типа того
обьекты не передавайте в конструктор, а пусть они запрашиваются через Core
Здравствуйте, enji, Вы писали:
E>Как можно сделать удобнее?
Если зависимости между модулями статические, можно их явно выписать и топологически отсортировать. (С диагностикой о циклических зависимостях).
Если зависимости постольку-поскольку (например, при старте не потребовалось ничего писать в журнал — ну и фиг с ним), — то можно ловить циклические зависимости в локаторе.
Как-то так