Я работаю над большим программным обеспечением, которое сильно зависит от супер-паттерна вызова.
По сути, интерфейс определяет виртуальный метод init()
, который затем переопределяется во всех классах, которые его наследуют.
Когда init()
вызывается для класса, КАЖДЫЕ перегруженные init
методы каскадируются, от базового класса до верхнего дочернего класса, и все между ними.
Но пользователь должен сам вызывать метод init()
своего прямого родителя, что приводит к следующему коду:
class myClass : public Base
{
virtual void init()
{
Parent::Init() // often forgotten, or misplaced by the developer
// Do some init stuff
}
}
Альтернативой этому обычно является использование делегатов. У базового класса есть вещи, которые нужно сделать в init
, которые объявлены final
в Base, и делегируют часть этого метода onInit()
, который наследующие классы должны переопределять. Но это не каскадно обращается ко всем родительским классам, как мне бы хотелось.
Альтернатива, которую я впервые реализовал, - это вариант делегированного подхода. И дочерние классы, и Base реализуют метод onInit()
и init()
.
init()
вызывает Parent::init()
с последующим вызовом onInit()
для себя и генерируется автоматически с использованием шаблонного метапрограммирования и макросов.
и onInit()
содержит код, специфичный для класса.
# define DELEGATE(T, Parent) \
void init() override { Parent::init(); T::onInit(); }
struct Base
{
virtual void init() { Base::onInit(); }
virtual void onInit() {}
};
struct A : public Base
{
DELEGATE(A, Base)
void onInit() override { /* MyCustom code for A */ }
};
struct B : public A
{
DELEGATE(B, A)
void onInit() override { /* MyCustom code for B */ }
};
Это работает довольно хорошо ... за исключением того, что множественное наследование становится беспорядком, и даже если обработано, наследование алмаза вызывает проблемы с дублированными вызовами.
Что заставляет меня задуматься: я не могу быть единственным человеком, который ищет шаблон проектирования, решающий мою проблему, и сообщество stackoverflow должно знать об этом:)
Вы когда-нибудь сталкивались с шаблоном дизайна для этого?
Я очень жду ваших идей!