Виртуальные функции при агрегации
От: MaximUN  
Дата: 16.08.11 05:20
Оценка:
Привет всем, возникла такая ситуация.
У нас есть некий объект/сущность — Entity. Этот объект довольно большой, и разделил его на несколько "слоев". Каждый слой обрабатывается своей подсистемой. Объект при конструировании надо зарегистрировать в подсистеме. Пока что таких слоев 3 штуки. У этих подсистем имеются разные реализации.

Вырисовывается что-то вроде:


class Entity {
public:
    Entity() {
        pSubSystem1->Register(this->layer1);  // Эта ф-ия создает нужную реализацию и возвращает ее
        pSubSystem2->Register(this->layer2);
        pSubSystem3->Register(this->layer3);
    };
    . . . 

private:
    ILayer1 *layer1;
    ILayer2 *layer2;
    ILayer3 *layer3;
};

class ILayer1 {
public:
    virtual void SomeOperaton1() = 0;
    virtual void SomeOperaton2() = 0;
    . . .

    virtual ~ILayer1() { };
};

// Где-то в DLL реализована подсистема, и layer-ы тоже
class Layer1_impl : public ILayer1 {
public:
    void SomeOperaton1() { ... };
    . . .
};


И все бы хорошо, однако теперь есть необходимость определять виртуальные ф-ии, которые можно было бы переопределять в Entity. Однако ж у меня тут агрегация, а не наследование, и сделать это никак не получится Наследовать от ILayer не получится, поэтому простейший вариант, создавать еще один класс, что-то типа ILayer1_operations и наследовать Entity от него, а в Layer1_impl хранить ссылку на этот классик.

Однако есть ли более элегантные варианты?
архитектура агрегация/наследование с++
Re: Виртуальные функции при агрегации
От: dfbag7 Россия  
Дата: 18.08.11 11:04
Оценка:
Здравствуйте, MaximUN, Вы писали:

MUN>Привет всем, возникла такая ситуация.


[skipped]

MUN>И все бы хорошо, однако теперь есть необходимость определять виртуальные ф-ии, которые можно было бы переопределять в Entity. Однако ж у меня тут агрегация, а не наследование, и сделать это никак не получится Наследовать от ILayer не получится, поэтому простейший вариант, создавать еще один класс, что-то типа ILayer1_operations и наследовать Entity от него, а в Layer1_impl хранить ссылку на этот классик.


MUN>Однако есть ли более элегантные варианты?


Агрегируемые классы должны содержать поддержку агрегирования. Эта самая поддержка, как правило, заключается в том, чтобы агрегируемый объект имел возможность известить своего владельца (агрегатора) об изменении своего состояния и позволял модифицировать свою реакцию на изменение состояния.

В современных языках типа C# это решается с помощью делегатов или аналогичных механизмов.
В C++ можно использовать boost::function, либо, в крайнем случае, пару из указателя на класс-агрегатор и на метод внутри этого класса (при этом получаем проблемы с сильным связыванием).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.