2012-05-15 15 views
11

Me enfrento al siguiente enigma: Nuestro software tiene una clase base abstracta para objetos de algoritmo. Todos estos objetos tienen un método común execute(), por ejemplo .:Parámetros genéricos (casi) autodescriptivos en C++ junto con una GUI?

class Algorithm 
{ 
public: 
    // [...] 
    virtual void execute() = 0; 
    // [...] 
}; 

Para cada algoritmo que queremos implementar, simplemente heredan de la clase base y almacenar todos los objetos cargados de algoritmos en una ubicación central. Hasta aquí todo bien.

El problema ahora radica en los parámetros de un algoritmo. Queremos ser capaces de describir para cada algoritmo los parámetros que deben establecerse (por una clase externa). Para este fin, le dimos a cada algoritmo un objeto ParameterList que contiene sus parámetros. Debo aclarar que, para nosotros, un parámetro consiste en una especie de tipo (como int) y una etiqueta (como "número de iteraciones).

El problema ahora comienza cuando queremos conectar el ParameterList a algún tipo de GUI. Obviamente, nuestros algoritmos no deberían tener "conocimiento" de la API gráfica (Qt, GTK, etc.) que estamos utilizando. Sin embargo, en el mismo lado, queremos poder describir semáforos semánticamente, por ejemplo especificando que el algoritmo requiere un nombre de fichero . Como se muestra a continuación, este nombre de fichero es hasta la interfaz gráfica de usuario.

¿hay una manera de combinar este ParameterList con algún tipo de conocimiento de tipo semántico?

Me doy cuenta de que esta pregunta suena muy vaga. Sin embargo, no tengo permitido publicar ningún ejemplo de código no trivial (por razones de NDA). Entonces, ¿alguien se ha enfrentado a un problema similar en el pasado?

Para concluir: queremos que nuestros objetos describan los parámetros que requieren una GUI, sin conocer los detalles exactos de la GUI.

+1

OK, ver, * eso es * una buena pregunta. Y de un nuevo póster, también. Hay esperanza despues de todo. –

+0

otro método virtual implementado en cada clase de algoritmo que proporciona la lista de los parámetros requeridos e información sobre el tipo (tal nombre de archivo -> luego un campo de texto con un botón de archivo abierto, entero -> botón de giro ...) y así sucesivamente ... la GUI pide que se muestren los parámetros para el algoritmo que se ejecutará ... ¿por qué no? – ShinTakezou

Respuesta

9

Una opción aquí podría ser utilizar el patrón de visitante. Puede crear una clase base como esto:

class Parameter { 
public: 
    virtual ~Parameter() {} // Polymorphic classes need virtual dtors. 

    virtual void accept(ParameterVisitor& v) = 0; 
}; 

se podría definir subclases como estos:

class IntParameter: public Parameter { 
public: 
    virtual void accept(ParameterVisitor& v) { 
      v.visit(*this); 
    } 
}; 
class FilenameParameter: public Parameter { 
public: 
    virtual void accept(ParameterVisitor& v) { 
      v.visit(*this); 
    } 
}; 

Nótese que en cada función accept miembro, el tipo de *this es el tipo estático de la clase - a saber, IntParameter& en el primer caso, y FilenameParameter& en el segundo caso.

continuación, se puede definir una clase base ParameterVisitor clase como esta:

class ParameterVisitor { 
public: 
    virtual ~ParameterVisitor() {} // Polymorphic classes need virtual dtors. 

    virtual void visit(IntParameter& p) {} 
    virtual void visit(FilenameParameter& p) {} 
    /* .. etc. .. */ 
}; 

entonces usted puede subclase este visitante para volver la información del tipo:

class Gui1ParameterVisitor: public ParameterVisitor { 
public: 
    virtual void visit(IntParameter& p) { 
     /* ... use GUI1 to create a field for an integer. */ 
    } 
    virtual void visit(FilenameParameter& p) { 
     /* ... use GUI1 to create a field for a filename. */ 
    } 
}; 

class Gui2ParameterVisitor: public ParameterVisitor { 
public: 
    virtual void visit(IntParameter& p) { 
     /* ... use GUI2 to create a field for an integer. */ 
    } 
    virtual void visit(FilenameParameter& p) { 
     /* ... use GUI2 to create a field for a filename. */ 
    } 
}; 

Su clase ParameterList continuación, puede simplemente tienda una lista de Parameter* s. A continuación, puede compilar la GUI instanciando el tipo de visitante apropiado y luego tener sus callbacks visit hacen toda la construcción del widget. Esto termina siendo seguro para tipos y recupera la información que necesita. Tiene el inconveniente de que cada vez que creas un nuevo tipo de parámetro, tienes que agregar una nueva función de miembro visit a la clase ParameterVisitor, pero tendrás que hacer eso de todos modos para hacer toda la construcción de la GUI.

Espero que esto ayude!

+0

esto es interesante, pero ¿no es demasiado complicado? ¿Por qué no una metainformación muy simple sobre cada parámetro, describiendo el tipo posible desde el cual la GUI extrae la interfaz necesaria? Tipo de "ffi" para GUI ... o similar – ShinTakezou

+1

El problema con la metainformación es que para tratar todo de manera genérica, necesitarías agregar un montón de código de la forma "si se trata de un campo int, así es como tú" crea el widget, así es como interpretas el widget, etc. " El enfoque anterior lo hace de una manera segura de tipo que no requiere ningún casting. – templatetypedef

+0

ah, por supuesto me falta la parte de "retroalimentación" que establece el valor seleccionado en la GUI de nuevo al objeto. Ok, ahora lo veo :) – ShinTakezou

Cuestiones relacionadas