Привет всем, возникла такая ситуация.
У нас есть некий объект/сущность — 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 хранить ссылку на этот классик.
Однако есть ли более элегантные варианты?
Здравствуйте, MaximUN, Вы писали:
MUN>Привет всем, возникла такая ситуация.
[skipped]
MUN>И все бы хорошо, однако теперь есть необходимость определять виртуальные ф-ии, которые можно было бы переопределять в Entity. Однако ж у меня тут агрегация, а не наследование, и сделать это никак не получится Наследовать от ILayer не получится, поэтому простейший вариант, создавать еще один класс, что-то типа ILayer1_operations и наследовать Entity от него, а в Layer1_impl хранить ссылку на этот классик.
MUN>Однако есть ли более элегантные варианты?
Агрегируемые классы должны содержать поддержку агрегирования. Эта самая поддержка, как правило, заключается в том, чтобы агрегируемый объект имел возможность известить своего владельца (агрегатора) об изменении своего состояния и позволял модифицировать свою реакцию на изменение состояния.
В современных языках типа C# это решается с помощью делегатов или аналогичных механизмов.
В C++ можно использовать boost::function, либо, в крайнем случае, пару из указателя на класс-агрегатор и на метод внутри этого класса (при этом получаем проблемы с сильным связыванием).