Frage

Ich habe eine Basisklasse, die abgeleiteten Unterklassen erben von, es trägt die grundlegenden Funktionen, die gleich in allen abgeleiteten Klassen sein sollte:

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

Nun, auf der Basis der abgeleiteten Klasse, möchte ich mehr case-Anweisungen an den Schalter ‚Hinzufügen‘. Was sind hier meine Optionen? Ich kann virtuelle Funktionen erklären und sie nur in den abgeleiteten Klassen definieren, die sie verwenden werden:

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() { ... }
}

Aber das würde bedeuten, wenn Funktionen in jeder abgeleiteten Klasse zu ändern, würde ich meine Basisklasse bearbeiten, um diese Änderungen widerzuspiegeln.

Gibt es ein Entwurfsmuster speziell für diese Art von Problem? Ich kaufte eine Reihe von Bücher über Design Patterns, aber ich bin ihnen auf „by-Bedarf“ -Basis zu studieren, so habe ich keine Ahnung, ob es ein solches Muster, das ich suche.

War es hilfreich?

Lösung

Sie können nützliche Informationen über Verantwortungskette Muster zu lesen und zu überdenken Ihre Lösung auf diese Weise.

Sie können auch erklären ‚doRun‘ als geschützte Methode und es in dem Basisstandardfall nennen.

default:
   doRun(input);

Und definiert doRun in abgeleiteten Klassen.

Dies wird so genannt Template-Methode Muster

Andere Tipps

Ich denke, das Muster, das Sie brauchen, ist Verantwortungskette oder vielleicht Strategie mit einem dynamischen Ruftabelle kombiniert ...

Der normale Weg des Umgangs mit dieser ist es, eine Fabrik zu verwenden. Kurz umrissen:

  • eine Hierarchie verwandter Klassen erstellen, die die Funktionalität bereitstellen.
  • eine Fabrik-Klasse erstellen, die die Eingabe und erstellt eine Instanz des rechten kindf der Klasse am Eingang
  • abhängig nehmen

Jetzt für zusätzliche Bonuspunkte:

  • erstellen ein Schema, das Klassen withn der Fabrik reghisters - Sie müssen den Eingang und den Typ der Klasse angeben, um damit umzugehen

Wenn nun ein Bedarf an einem neuen Eingang entlang kommt, leiten Sie nur eine neue Klasse und registrieren Sie es mit der Fabrik. Die Notwendigkeit für die Switch-Anweisung verschwindet.

Wenn Sie Ihre Selektorwerte sind nur kleine ganze Zahlen, würde ich die Case-Anweisung durch eine Lookup-Tabelle ersetzen. (Die Aktionen im Fall müssen jeweils als Funktion kodiert werden, so dass Sie Funktionszeiger in dem Tisch legen können). Dann können geerbte Klassen fügen Sie einfach Einträge in die Tabelle. (Ich denke, die Tabelle eine Instanz Eigenschaft sein müßte, kann es nicht statisch sein).

Colin

  

Aber das würde bedeuten, bei einem Wechsel   Funktionen in jeder abgeleiteten Klasse I   müßte meine Basisklasse bearbeiten, um   spiegeln diese Änderungen.

Warum sollte das wahr sein?

Ich zünde Ihren Kommentar - dann, wenn Sie diesen Ansatz wählen Sie diese Probleme werden müssen. Andere haben Antworten geschrieben, die anderen Lösungen vorschlagen -. Ich diese heraus überprüfen würde, um zu sehen, ob sie Ihnen helfen,

А einfache Lösung:

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;
    }
...

... und dann implementieren zusätzliche Fälle in der Unterklasse Process (). Wenn Sie mehr als 2 Ebenen unterstützen müssen (das heißt Unterunterklasse indem noch mehr Fälle), dann werden Sie eine dynamische Dispatch-Tabelle benötigen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top