Domanda

Ho una classe di base che sottoclassi derivate ereditano da, porta le funzioni di base che dovrebbero essere la stessa in tutte le classi derivate:

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

Ora, in base alla classe derivata, voglio 'aggiungere' più istruzioni case allo switch. quali sono le mie opzioni? Posso dichiarare funzioni virtuali e solo definire le classi derivate che stanno per usarli:

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

Ma questo vorrebbe dire quando si cambiano le funzioni in ogni classe derivata, avrei dovuto modificare il mio classe di base per riflettere tali cambiamenti.

C'è un modello di progettazione appositamente per questo tipo di problema? Ho acquistato un certo numero di libri su Design Patterns, ma li sto studiando su base "per-bisogno", quindi non ho idea se v'è una tale modello che sto cercando.

È stato utile?

Soluzione

Si possono trovare utile leggere sulla catena di responsabilità modello e ripensare la soluzione in questo modo.

Inoltre è possibile dichiarare 'doRun' come metodo protetto e chiamarlo nel caso di default di base.

default:
   doRun(input);

E definire doRun nelle classi derivate.

Questo è il cosiddetto modello Template Method

Altri suggerimenti

Credo che il modello che vi serve è catena di responsabilità o forse Strategia in combinazione con una tabella chiamata dinamica ...

Il modo normale di affrontare questo è quello di utilizzare una fabbrica. A grandi linee:

  • creare una gerarchia di classi correlate che forniscono la funzionalità.
  • creare una classe factory che prende l'input e crea un'istanza del diritto kindf di classe a seconda dell'ingresso

Ora per i punti bonus aggiunto:

  • creare uno schema che reghisters classi withn fabbrica - sarà necessario specificare l'ingresso ed il tipo della classe a che fare con esso

Ora, quando la necessità di un nuovo input arriva, basta derivare una nuova classe e registrarlo con la fabbrica. La necessità per l'istruzione switch scompare.

Se i valori del selettore sono solo piccoli interi, vorrei sostituire l'istruzione caso per una tabella di ricerca. (Le azioni nel caso necessarie a ciascuno di essere codificato come una funzione, in modo da poter mettere puntatori a funzione nella tabella). Poi classi ereditate possono semplicemente aggiungere voci alla tabella. (Credo che la tabella dovrebbe essere una proprietà di istanza, non può essere statica).

Colin

  

Ma questo vorrebbe dire quando si cambia   funziona in ogni classe derivata, io   avrebbe dovuto modificare il mio classe di base per   riflettere tali cambiamenti.

Perché questo essere vero?

I luce del tuo commento - quindi se si sceglie questo metodo avrai questi problemi. Altri hanno inviato le risposte che suggeriscono altre soluzioni -. Mi piacerebbe controllare questi fuori per vedere se si aiutano

soluzione semplice А:

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

... e quindi implementare ulteriori casi in sottoclasse Process (). Se avete bisogno di supportare più di 2 livelli (vale a dire sotto-sottoclasse aggiungendo ancora più casi), allora avrete bisogno di un tavolo dispaccio dinamica.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top