Question

J'ai une classe de base qui sous-classes dérivées héritent, il porte les fonctions de base qui devraient être les mêmes dans toutes les classes dérivées:

class Basic {
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            case 1:
                doA();
                break;
            case 2:
                doB();
                break;
            case 5:
                Foo();
                break;
        }
    }
};

Maintenant, en fonction de la classe dérivée, je veux « ajouter » autres déclarations de cas au commutateur. Quelles sont mes options ici? Je peux déclarer des fonctions virtuelles et ne les définir dans les classes dérivées qui vont les utiliser:

class Basic {
protected:
    virtual void DoSomethingElse();
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            ...

            case 6:
                DoSomethingElse();
        }
    }
};


class Derived : public Basic {
protected:
    void DoSomethingElse() { ... }
}

Mais cela signifierait en cas de changement des fonctions dans une classe dérivée, je dois modifier ma classe de base pour refléter ces changements.

Y at-il un modèle de conception spécifiquement pour ce genre de question? J'ai acheté un certain nombre de livres sur le design patterns, mais je les étudier sur je base « par nécessité », donc aucune idée s'il y a un tel modèle que je cherche.

Était-ce utile?

La solution

Vous trouverez peut-être utile de lire chaîne de modèle responsabilité et repenser votre solution de cette façon.

Aussi, vous pouvez déclarer « doRun » comme méthode protégée et l'appeler dans le cas par défaut de base.

default:
   doRun(input);

Et définir doRun dans les classes dérivées.

Il en est ainsi appelée Template motif Méthode

Autres conseils

Je pense que le modèle dont vous avez besoin est Chaîne de responsabilité ou peut-être Stratégie associée à une table d'appel dynamique ...

La façon normale de traiter est d'utiliser une usine. Dans les grandes lignes:

  • créer une hiérarchie de classes connexes qui fournissent la fonctionnalité.
  • créer une classe d'usine qui prend l'entrée et crée une instance du droit kindf de classe en fonction de l'entrée

pour des points bonus ajoutés:

  • créer un système qui reghisters cours withn l'usine - vous devrez spécifier l'entrée et le type de la classe pour y faire face

Maintenant, quand besoin d'une nouvelle entrée se présente, vous dérivez juste une nouvelle classe et l'enregistrer avec l'usine. La nécessité de l'instruction switch disparaît.

Si vos valeurs de sélection ne sont que de petits entiers, je remplacerais la déclaration de cas par une table de consultation. (Les actions dans le cas leur faudra être codées en fonction, de sorte que vous pouvez mettre des pointeurs de fonction dans le tableau). Ensuite, les classes héritées peuvent simplement ajouter des entrées à la table. (Je suppose que la table devrait être une propriété d'instance, il ne peut pas être statique).

Colin

  

Mais cela signifierait lors du changement   les fonctions de toute classe dérivée, I   aurait à modifier ma classe de base   tenir compte de ces changements.

Pourquoi serait-ce vrai?

Je la lumière de votre commentaire - alors si vous choisissez cette approche, vous aurez ces questions. D'autres ont posté des réponses qui suggèrent d'autres solutions -. Je vérifier ces pour voir si elles vous aider

А solution simple:

class Basic {
  public:
    void Run() {
      const int input = ...
      if (!(BaseProcess(input) || Process(input))) ...
    }

    vitual bool Process(int input) { return false; }

    bool BaseProcess(int input) {
      switch(input) {
    ...
        default: return false;
      }
      return true;
    }
...

... et puis mettre en œuvre des cas supplémentaires dans la sous-classe Process (). Si vous avez besoin de prendre en charge plus de 2 niveaux (à savoir sous-sous-classe ajoutant encore plus de cas), alors vous aurez besoin d'un tableau de répartition dynamique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top