Pregunta

Tengo una clase básica de que las subclases heredan de derivados, que lleva las funciones básicas que deben ser los mismos en todas las clases derivadas:

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

Ahora, en base a la clase derivada, quiero 'añadir' más sentencias de caso para el interruptor. ¿Cuáles son mis opciones aquí? Puedo declarar funciones virtuales y sólo definirlos en las clases derivadas que van a utilizarlos:

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

Pero esto significaría al cambiar las funciones de cualquier clase derivada, que tendría que editar mi clase base para reflejar esos cambios.

¿Hay un patrón de diseño específicamente para este tipo de problema? He comprado un número de libros sobre patrones de diseño, pero los estoy estudiando en la base "por necesidad", así que no tengo ni idea de si existe un patrón tal que yo estoy buscando.

¿Fue útil?

Solución

Puede resultar útil leer información sobre el cadena de responsabilidades patrón y replantear su solución de esa manera.

También se puede declarar 'doRun' como método protegido y lo llaman en el caso por defecto de base.

default:
   doRun(input);

Y definir doRun en las clases derivadas.

Esto se llama así Método Plantilla

Otros consejos

Creo que el patrón de lo que necesita es cadena de responsabilidad o tal vez Estrategia en combinación con una tabla llamada dinámica ...

La manera normal de hacer frente a esto es utilizar una fábrica. En resumen:

  • crear una jerarquía de clases relacionadas que proporcionan la funcionalidad.
  • crear una clase de fábrica que toma la entrada y crea una instancia de la clase derecha de kindf dependiendo de la entrada

Ahora, para los puntos de bonificación agregados:

  • crear un esquema que reghisters clases withn la fábrica - tendrá que especificar la entrada y el tipo de la clase para tratar con él

Ahora, cuando la necesidad de una nueva entrada llega, que acaba de derivar una nueva clase y registrarlo en la fábrica. La necesidad de la instrucción switch desaparece.

Si sus valores de selector son sólo pequeños números enteros, que sustituiría a la declaración de caso por una tabla de consulta. (Las acciones en el caso tendrán cada uno tenga que ser codificada como una función, lo que puede poner los punteros de función en la tabla). A continuación, las clases heredadas solo se pueden añadir entradas a la tabla. (Supongo que la mesa tendría que ser una propiedad de instancia, no puede ser estática).

Colin

  

Pero esto significaría al cambiar   funciona en cualquier clase derivada, I   tendría que editar mi clase base a   reflejar esos cambios.

¿Por qué esto es verdad?

luz de su comentario - a continuación, si elige este método tendrá estos problemas. Otros han publicado respuestas que sugieren otras soluciones -. Me echa un vistazo a estos para ver si te ayudan

solución 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;
    }
...

... y luego implementar casos adicionales en subclase Proceso (). Si tiene que soportar más de 2 niveles (es decir, sub-subclase añadiendo aún más casos), entonces necesitará una mesa de despacho dinámico.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top