ШВ
FooType *gimmeFoo(const FooId&);
BarType *gimmeBar(const BarId&);
внутри может быть тупо registry.
Но тогда резонный вопрос откуда приходят идентификаторы для Foo и Bar?
Если они определнны еще у кого-то: struct IHaveFooAndBarIds { FooId fooId; BarId barId; };
Но такое на мой взгляд имет смысл, только если можно сделать больше одного действия по FooId
