Возьмем модульную архитектуру , есть несколько базовых типов объектов, каждый базовый тип описан в своем модуле.
У каждого базового типа есть производные типы, в зависимости от состояния программы ( оно одно для всех ) используется тот или иной производный тип.
в коде в зависимости от состояния нужно выбирать нужный объект
CBaseA* object_a;
switch( state )
{
case 1: object_a = new CDerivedA1(); break;
case 2: object_a = new CDerivedA2(); break;
}
естественно это использовать во всех местах кода где идет использование объекта типа CBaseA неудобно и лучше сделать 1 раз фабричный метод
static CBaseA* CreateObjectA()
{
switch( state )
{
case 1: return new CDerivedA1();
case 2: return new CDerivedA2();
}
}
Вот возникает вопрос, где лучше этот метод описать — есть 2 варианта , 1й — в самом базовом типе CBaseA, CBaseB и т.д. C,D,E... в виде статического метода, 2й — создать статический тип CObjectFactory и в нем статическими методами описать создание объектов каждого типа A, B, C, D и т.д.
Что же получается в результате в обоих вариантах — зацикленность или избыточность ссылок
1й вариант — получается зацикленность ссылок, то есть если раньше базовый тип ничего не знал о объектах которые от него наследуются , то теперь для того чтобы базовый тип мог создавать производные нужно ему включить include все хедеры производных типов. Также минус в том что состояние в данном случае придется хранить для каждого объекта или выносить в отдельный статический синглетон.
2й вариант — синглетон CObjectFactory который может создать объект любого типа A, B, C и т.д., он получается зависим от всех модулей, при этом остальные модули вроде как от него отделены и не связаны между собой — на первый взгляд то что нужно. Но вот допустим модуль B решил использовать объект модуля А , соотвественно создать этот объект он теперь должен через фабрику, как только мы подключим фабрику получится что объект модуля B становится зависим от всех остальных модулей которые фабрика может создавать.
Как это решается ?