Организация взаимосвязанных классов

Подскажите, пожалуйста, как правильно поступить в следующей ситуации.

class A {
    B* b;
public:
    A() {
        b = new B(*this); 
    }
    
    B* getB();
}

class B {
    A& a;
public:
    B(A& a) {
        this->a = a;
    }
    
    void foo() {
        /* 
            вызов функции из другой библиотеки
            для вызываемой функции важно знать
            некоторые поля объекта a
        */
    }
}

int main() {
    A* a = new A();
    a->getB()->foo();
}

Мне кажется, что взаимное хранение объектов двух классов не есть хорошая идея. Класс A является главным и состоит из десятков классов, похожих на B. То есть в каждом классе вроде B должна храниться ссылка на объект класса A. При этом класс B не может существовать без класса A, а класс A спокойно может существовать без класса B. Поэтому и используется в одном случае ссылка, в другом - указатель.

Почему я отделяю логику класса B от класса A? К сожалению, класс B содержит слишком большое количество своих методов, реализующих те или иные задачи. В связи с этим и решил, что не стоит забивать класс A, а имеет смысл выделить это в отдельный класс.

На самом деле где-то в глубине души есть надежда, что существует какой-нибудь паттерн для подобного случая. Но, просмотрев список паттернов, ничего подобного не нашел...


Ответы (1 шт):

Автор решения: Roman Konoval

Если В нужны все лишь некоторые методы из А, то ему не обязатьельно знать про (и зависеть от А). Создайте интерфейс, который умеет давать для В то, что ему нужно от А:

class SomePortionOfA
{
    public:
        virtual C something() = 0;
};

class A : public SomePortionOfA {
    public:
        C something() {
        }

        // другие методы
}

class B {
    SomePortionOfA& a;
public:
    B(SomePortionOfA& a) {
        this->a = a;
    }
    
    void foo() {
        /* 
            вызов функции из другой библиотеки
            для вызываемой функции важно знать
            некоторые поля объекта a
        */
        a.something();
    }
}

Теперь В не зависит от А. А и В зависят от SomePortionOfA. То что мы сейчас сделали называется инверсия зависимости.

→ Ссылка