Метод переопределения для семейства подклассов

Учитывая унаследованный код, система имеет следующую иерархию классов:

          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 возможных решения, которые мне не очень нравятся:

  1. Реализовать Base :: SpecificPartOfFunctionality в каждом An..En.

    Проблема с этим решением состоит в том, что реализация должна быть точно такой же для каждого класса, поэтому я просто повторяю код.

    Дополнительная проблема заключается в том, что если вводится новый класс Fn, разработчик может забыть реализовать SpecificPartOfFunctionality .

  2. Ввести класс BaseN , производный от Base, в то время как каждый An..En унаследованы от BaseN тоже:

     class BaseN: public Base {
      // ...
      SpecificPartOfFunctionality () {...}
     };
    
    класс An: общественный Ан-1, общественный BaseN {..}
     

    Проблема с этим решением состоит в том, что оно вводит проблему алмаза .

    Дополнительная проблема заключается в том, что произойдет, если в какой-то другой версии m потребуется также переопределить Base :: SpecificPartOfFunctionality . Следуя решению, мы представим BaseM , который переопределит Base :: SpecificPartOfFunctionality . Таким образом, SpecificPartOfFunctionality будет вызываться для An - из BaseN или для BaseN . Это полный беспорядок.

Есть предложения?

5
задан Fred Nurk 14 May 2011 в 23:44
поделиться