Учитывая унаследованный код, система имеет следующую иерархию классов:
Base
^
|
----------+---------------
^ ^ ^ ^ ^
| | | | |
A1 B1 C1 D1 E1
^ ^ ^ ^ ^
| | | | |
A2 B2 C2 D2 E2
.......
^ ^ ^ ^ ^
| | | | |
An Bn Cn Dn En
Иерархия представляет сообщения в некотором конкретном домене.
Базовый класс - это, конечно же, базовый класс всех сообщений. A1..E1 - это сообщения, принадлежащие версии 1 домена, A2..E2 - версии 2 и так далее. Обратите внимание, что An должен наследовать напрямую от An-1, поскольку An переопределяет определенные методы An-1.
Есть некоторые функции, общие для всех сообщений, поэтому он определен как Base :: PerformFunctionality . Некоторая часть функциональности специфична только для версии n , поэтому есть виртуальная функция Base :: SpecificPartOfFunctionality , которая вызывается Base :: PerformFunctionality .
] Итак, моя проблема в том, как переопределить Base :: SpecificPartOfFunctionality всеми An..En.
Я вижу 2 возможных решения, которые мне не очень нравятся:
Реализовать Base :: SpecificPartOfFunctionality в каждом An..En.
Проблема с этим решением состоит в том, что реализация должна быть точно такой же для каждого класса, поэтому я просто повторяю код.
Дополнительная проблема заключается в том, что если вводится новый класс Fn, разработчик может забыть реализовать SpecificPartOfFunctionality .
Ввести класс BaseN , производный от Base, в то время как каждый An..En унаследованы от BaseN тоже:
class BaseN: public Base {
// ...
SpecificPartOfFunctionality () {...}
};
класс An: общественный Ан-1, общественный BaseN {..}
Проблема с этим решением состоит в том, что оно вводит проблему алмаза .
Дополнительная проблема заключается в том, что произойдет, если в какой-то другой версии m потребуется также переопределить Base :: SpecificPartOfFunctionality . Следуя решению, мы представим BaseM , который переопределит Base :: SpecificPartOfFunctionality . Таким образом, SpecificPartOfFunctionality будет вызываться для An - из BaseN или для BaseN . Это полный беспорядок.
Есть предложения?